import sys, os, types
import windowsUi

import version

from PyQt4.QtGui import QApplication, QMessageBox
import sys

command = None
proxy = None


def run_as_admin(cmd_line=None, wait=True):
    try:
        if os.name != 'nt':
            raise RuntimeError, "This function is only implemented on Windows."

        import win32con, win32event, win32process
        from win32com.shell.shell import ShellExecuteEx
        from win32com.shell import shellcon

        python_exe = sys.executable

        if cmd_line is None:
            cmd_line = [python_exe] + sys.argv
        elif type(cmd_line) not in (types.TupleType, types.ListType):
            raise ValueError, "cmdLine is not a sequence."
        cmd = '%s' % (cmd_line[0],)
        # TODO: isn't there a function or something we can call to massage command line params?
        params = " ".join(['%s' % (x,) for x in cmd_line[1:]])
        # cmdDir = ''
        show_cmd = win32con.SW_SHOWNORMAL
        # showCmd = win32con.SW_HIDE
        lp_verb = 'runas'  # causes UAC elevation prompt.

        # print "Running", cmd, params

        # ShellExecute() doesn't seem to allow us to fetch the PID or handle
        # of the process, so we can't get anything useful from it. Therefore
        # the more complex ShellExecuteEx() must be used.

        # procHandle = win32api.ShellExecute(0, lpVerb, cmd, params, cmdDir, showCmd)

        print "cmd: ", cmd
        print "Params: ", params

        proc_info = ShellExecuteEx(nShow=show_cmd,
                                  fMask=shellcon.SEE_MASK_NOCLOSEPROCESS,
                                  lpVerb=lp_verb,
                                  lpFile=cmd,
                                  lpParameters=params)

        if wait:
            proc_handle = proc_info['hProcess']
            win32event.WaitForSingleObject(proc_handle, win32event.INFINITE)
            rc = win32process.GetExitCodeProcess(proc_handle)
            # print "Process handle %s returned code %s" % (proc_handle, rc)
            return rc
        else:
            return -1
    except Exception as _:
        return -1


def open_ui():
    """
        Open UI to inform the user
    """

    # app = QApplication(sys.argv)  # only dev
    
    pass_ui = windowsUi.Windows_dialog()
    pass_ui.show()

    if pass_ui.exec_():

        global proxy
        if pass_ui.get_proxy():
            proxy = '--proxy="{}"'.format(pass_ui.get_proxy())
        else:
            proxy = ""

    del pass_ui
    global command

    osgeo_root = os.popen('echo %OSGEO4W_ROOT%').read().replace('\n', '')
    command = os.path.join(osgeo_root, 'OSGeo4W.bat')


def install_pip():
    """
        Install pip from local get-pip.py
    """
    if not command:
        open_ui()

    path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'get_pip', 'get-pip.py')

    params = 'python {}'.format(path)
    rc = run_as_admin([command, params], wait=True)
    if rc != 0:
        QMessageBox.warning(None, "Problem during installation", "Problem installing pip")
        return False
    return True


def install_numpy():
    """
        install numpy using whl file inside numpy directory
    """
    import platform

    os_ver = platform.architecture()[0]

    if os_ver == '64bit':
        numpy_link = "http://www.silx.org/pub/wheelhouse/old/numpy-1.11.1+mkl-cp27-cp27m-win_amd64.whl"
    else:
        numpy_link = "http://www.silx.org/pub/wheelhouse/old/numpy-1.11.1+mkl-cp27-cp27m-win32.whl"

    if not command:
        open_ui()

    params = 'python -m pip install {} {}'.format(numpy_link, proxy)
    rc = run_as_admin([command, params], wait=True)

    if rc != 0:
        QMessageBox.warning(None, "Problem during installation", "Problem installing numpy")
        return False
    return True


def install_flopy():
    """
        Install flopy without dependencies
    """
    if not command:
        open_ui()

    params = 'python -m pip install -U --no-deps --upgrade flopy=={} {}'.format(version.flopy, proxy)

    rc = run_as_admin([command, params], wait=True)

    if rc != 0:
        QMessageBox.warning(None, "Problem during installation", "Problem installing flopy")
        return False
    return True


def install_missing_dep(package):
    """
        Install missing freewat dependencies
    """

    packages = ""

    for dep in package.keys():

        if package[dep] or dep == 'pip' or dep == 'numpy':
            continue

        if dep == "pandas":
            packages += " pandas=={}".format(version.pandas)
        elif dep == "flopy":
            flag = install_flopy()
            if not flag:
                return
        else:
            packages += " {}".format(dep)

    if len(packages) == 0:
        write_file()
        return

    if not command:
        open_ui()

    params = 'python -m pip install{} {}'.format(packages, proxy)
    rc = run_as_admin([command, params], wait=True)

    if rc != 0:
        QMessageBox.warning(None, "Problem during installation", "Problem during installation, please try again")
    else:
        rc = write_file()

        if rc == 0:
            QMessageBox.warning(None, "Installation done", "FREEWAT plugin is ready to use!")


def write_file():
    """
        Write file to confirm that dependencies are installed
    """
    if not command:
        open_ui()

    path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'writeFile.py')
    params = "python {}".format(path)
    rc = run_as_admin([command, params], wait=True)

    global proxy
    del proxy

    return rc
