#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Copyright (c) 2002 - 2018 Detlev Offenbach <detlev@die-offenbachs.de>
#
# This is the uninstall script for eric6.
#

"""
Uninstallation script for the eric6 IDE and all eric6 related tools.
"""

from __future__ import unicode_literals, print_function

import sys
import os
import shutil
import glob
import distutils.sysconfig

if sys.version_info[0] == 2:
    try:
        from PyQt5 import sip
    except ImportError:
        import sip
    sip.setapi('QString', 2)
else:
    raw_input = input

# get a local eric6config.py out of the way
if os.path.exists("eric6config.py"):
    os.rename("eric6config.py", "eric6config.py.orig")
from eric6config import getConfig

# Define the globals.
progName = None
currDir = os.getcwd()
pyModDir = None
progLanguages = ["Python", "Ruby", "QSS"]
includePythonVariant = False
defaultMacAppBundleName = "eric6.app"
defaultMacAppBundlePath = "/Applications"
settingsNameOrganization = "Eric6"
settingsNameGlobal = "eric6"

# Define file name markers for Python variants
PythonMarkers = {
    2: "_py2",
    3: "_py3",
}


def exit(rcode=0):
    """
    Exit the uninstall script.
    
    @param rcode result code to report back (integer)
    """
    global currDir
    
    # restore the local eric6config.py
    if os.path.exists("eric6config.py.orig"):
        if os.path.exists("eric6config.py"):
            os.remove("eric6config.py")
        os.rename("eric6config.py.orig", "eric6config.py")
    
    if sys.platform.startswith("win"):
        # different meaning of input between Py2 and Py3
        try:
            input("Press enter to continue...")
        except (EOFError, SyntaxError):
            pass
    
    os.chdir(currDir)
    
    sys.exit(rcode)


def usage(rcode=2):
    """
    Display a usage message and exit.

    @param rcode return code passed back to the calling process (integer)
    """
    global progName

    print("Usage:")
    print("    {0} [-h]".format(progName))
    print("where:")
    print("    -h             display this help message")
    print("    -y             remove executables with Python variant in name")

    exit(rcode)


def initGlobals():
    """
    Set the values of globals that need more than a simple assignment.
    """
    global pyModDir

    pyModDir = distutils.sysconfig.get_python_lib(True)


def wrapperName(dname, wfile):
    """
    Create the platform specific name for the wrapper script.
    
    @param dname name of the directory to place the wrapper into
    @param wfile basename (without extension) of the wrapper script
    @return the name of the wrapper script
    """
    if sys.platform.startswith("win"):
        wname = dname + "\\" + wfile + ".bat"
    else:
        wname = dname + "/" + wfile

    return wname


def uninstallEric():
    """
    Uninstall the eric files.
    """
    global pyModDir
    
    # Remove the menu entry for Linux systems
    if sys.platform.startswith("linux"):
        if os.getuid() == 0:
            for name in ["/usr/share/pixmaps/eric.png",
                         "/usr/share/pixmaps/ericWeb.png"]:
                if os.path.exists(name):
                    os.remove(name)
            if includePythonVariant:
                marker = PythonMarkers[sys.version_info.major]
            else:
                marker = ""
            for name in [
                "/usr/share/applications/eric6" + marker + ".desktop",
                "/usr/share/appdata/eric6" + marker + ".appdata.xml",
                "/usr/share/metainfo/eric6" + marker + ".appdata.xml",
                "/usr/share/applications/eric6_webbrowser" + marker +
                ".desktop",
                "/usr/share/applications/eric6_browser" + marker +
                ".desktop",
                "/usr/share/pixmaps/eric" + marker + ".png",
                "/usr/share/pixmaps/ericWeb" + marker + ".png",
            ]:
                if os.path.exists(name):
                    os.remove(name)
        elif os.getuid() >= 1000:
            # it is assumed that user ids start at 1000
            for name in ["~/.local/share/pixmaps/eric.png",
                         "~/.local/share/pixmaps/ericWeb.png"]:
                path = os.path.expanduser(name)
                if os.path.exists(path):
                    os.remove(path)
            if includePythonVariant:
                marker = PythonMarkers[sys.version_info.major]
            else:
                marker = ""
            for name in [
                "~/.local/share/applications/eric6" + marker + ".desktop",
                "~/.local/share/appdata/eric6" + marker + ".appdata.xml",
                "~/.local/share/metainfo/eric6" + marker + ".appdata.xml",
                "~/.local/share/applications/eric6_webbrowser" + marker +
                ".desktop",
                "~/.local/share/applications/eric6_browser" + marker +
                ".desktop",
                "~/.local/share/pixmaps/eric" + marker + ".png",
                "~/.local/share/pixmaps/ericWeb" + marker + ".png",
            ]:
                path = os.path.expanduser(name)
                if os.path.exists(path):
                    os.remove(path)
    
    # Remove the wrapper scripts
    rem_wnames = [
        "eric6_api", "eric6_compare",
        "eric6_configure", "eric6_diff",
        "eric6_doc", "eric6_qregularexpression",
        "eric6_qregexp", "eric6_re",
        "eric6_trpreviewer", "eric6_uipreviewer",
        "eric6_unittest", "eric6",
        "eric6_tray", "eric6_editor",
        "eric6_plugininstall", "eric6_pluginuninstall",
        "eric6_pluginrepository", "eric6_sqlbrowser",
        "eric6_webbrowser", "eric6_iconeditor",
        "eric6_snap", "eric6_hexeditor", "eric6_browser",
        "eric6_shell",
    ]
    if includePythonVariant:
        marker = PythonMarkers[sys.version_info.major]
        rem_wnames = [n + marker for n in rem_wnames]
    
    try:
        for rem_wname in rem_wnames:
            rwname = wrapperName(getConfig('bindir'), rem_wname)
            if os.path.exists(rwname):
                os.remove(rwname)
        
        # Cleanup our config file(s)
        for name in ['eric6config.py', 'eric6config.pyc', 'eric6.pth']:
            e5cfile = os.path.join(pyModDir, name)
            if os.path.exists(e5cfile):
                os.remove(e5cfile)
            e5cfile = os.path.join(pyModDir, "__pycache__", name)
            path, ext = os.path.splitext(e5cfile)
            for f in glob.glob("{0}.*{1}".format(path, ext)):
                os.remove(f)
        
        # Cleanup the install directories
        for name in ['ericExamplesDir', 'ericDocDir', 'ericDTDDir',
                     'ericCSSDir', 'ericIconDir', 'ericPixDir',
                     'ericTemplatesDir', 'ericCodeTemplatesDir',
                     'ericOthersDir', 'ericStylesDir', 'ericDir']:
            dirpath = getConfig(name)
            if os.path.exists(dirpath):
                shutil.rmtree(dirpath, True)
        
        # Cleanup translations
        for name in glob.glob(
                os.path.join(getConfig('ericTranslationsDir'), 'eric6_*.qm')):
            if os.path.exists(name):
                os.remove(name)
        
        # Cleanup API files
        apidir = getConfig('apidir')
        if apidir:
            for progLanguage in progLanguages:
                for name in getConfig('apis'):
                    apiname = os.path.join(apidir, progLanguage.lower(), name)
                    if os.path.exists(apiname):
                        os.remove(apiname)
                for apiname in glob.glob(
                        os.path.join(apidir, progLanguage.lower(), "*.bas")):
                    if os.path.basename(apiname) != "eric6.bas":
                        os.remove(apiname)
        
        if sys.platform == "darwin":
            # delete the Mac app bundle
            if os.path.exists("/Developer/Applications/Eric6"):
                shutil.rmtree("/Developer/Applications/Eric6")
            try:
                macAppBundlePath = getConfig("macAppBundlePath")
                macAppBundleName = getConfig("macAppBundleName")
            except AttributeError:
                macAppBundlePath = defaultMacAppBundlePath
                macAppBundleName = defaultMacAppBundleName
            for bundlePath in [os.path.join(defaultMacAppBundlePath,
                                            macAppBundleName),
                               os.path.join(macAppBundlePath,
                                            macAppBundleName),
                               ]:
                if os.path.exists(bundlePath):
                    shutil.rmtree(bundlePath)
        
        # remove plug-in directories
        removePluginDirectories()
        
        # remove the eric data directory
        removeDataDirectory()
        
        # remove the eric configuration directory
        removeConfigurationData()
        
        print("\nUninstallation completed")
    except (IOError, OSError) as msg:
        sys.stderr.write(
            'Error: {0}\nTry uninstall with admin rights.\n'.format(msg))
        exit(7)


def removePluginDirectories():
    """
    Remove the plug-in directories.
    """
    pathsToRemove = []
    
    globalPluginsDir = os.path.join(getConfig('mdir'), "eric6plugins")
    if os.path.exists(globalPluginsDir):
        pathsToRemove.append(globalPluginsDir)
    
    localPluginsDir = os.path.join(getConfigDir(), "eric6plugins")
    if os.path.exists(localPluginsDir):
        pathsToRemove.append(localPluginsDir)
    
    if pathsToRemove:
        print("Found these plug-in directories")
        for path in pathsToRemove:
            print("  - {0}".format(path))
        answer = "c"
        while answer not in ["y", "Y", "n", "N", ""]:
            answer = raw_input(
                "Shall these directories be removed (y/N)? ")
        if answer in ["y", "Y"]:
            for path in pathsToRemove:
                shutil.rmtree(path)


def removeDataDirectory():
    """
    Remove the eric data directory.
    """
    cfg = getConfigDir()
    if os.path.exists(cfg):
        print("Found the eric data directory")
        print("  - {0}".format(cfg))
        answer = "c"
        while answer not in ["y", "Y", "n", "N", ""]:
            answer = raw_input(
                "Shall this directory be removed (y/N)? ")
        if answer in ["y", "Y"]:
            shutil.rmtree(cfg)


def removeConfigurationData():
    """
    Remove the eric configuration directory.
    """
    try:
        from PyQt5.QtCore import QSettings
    except ImportError:
        try:
            from PyQt4.QtCore import QSettings
        except ImportError:
            print("No PyQt variant installed. The configuration directory")
            print("cannot be determined. You have to remove it manually.\n")
            return
    
    settings = QSettings(QSettings.IniFormat, QSettings.UserScope,
                         settingsNameOrganization, settingsNameGlobal)
    settingsDir = os.path.dirname(settings.fileName())
    if os.path.exists(settingsDir):
        print("Found the eric configuration directory")
        print("  - {0}".format(settingsDir))
        answer = "c"
        while answer not in ["y", "Y", "n", "N", ""]:
            answer = raw_input(
                "Shall this directory be removed (y/N)? ")
        if answer in ["y", "Y"]:
            shutil.rmtree(settingsDir)


def getConfigDir():
    """
    Module function to get the name of the directory storing the config data.
    
    @return directory name of the config dir (string)
    """
    cdn = ".eric6"
    return os.path.join(os.path.expanduser("~"), cdn)


def main(argv):
    """
    The main function of the script.

    @param argv list of command line arguments
    """
    import getopt

    global includePythonVariant
    
    initGlobals()

    # Parse the command line.
    global progName
    progName = os.path.basename(argv[0])

    try:
        optlist, args = getopt.getopt(argv[1:], "hy")
    except getopt.GetoptError:
        usage()

    global platBinDir

    for opt, _arg in optlist:
        if opt == "-h":
            usage(0)
        if opt == "-y":
            includePythonVariant = True
    
    print("\nUninstalling eric6 ...")
    uninstallEric()
    print("\nUninstallation complete.")
    print()
    
    exit(0)


if __name__ == "__main__":
    try:
        main(sys.argv)
    except SystemExit:
        raise
    except Exception:
        print("""An internal error occured.  Please report all the output of"""
              """ the program,\n"""
              """including the following traceback, to"""
              """ eric-bugs@eric-ide.python-projects.org.\n""")
        raise

#
# eflag: noqa = M801
