# -*- coding: utf-8 -*-

# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing the pip interface plug-in.
"""

from __future__ import unicode_literals


from PyQt5.QtCore import pyqtSignal, QObject, QCoreApplication

from E5Gui.E5Application import e5App

import Preferences
import UI.Info

# Start-Of-Header
name = "pip Interface Plug-in"
author = "Detlev Offenbach <detlev@die-offenbachs.de>"
autoactivate = True
deactivateable = True
version = UI.Info.VersionOnly
className = "PipInterfacePlugin"
packageName = "__core__"
shortDescription = "Plug-in implementing a simple GUI for the pip command."
longDescription = (
    """Plug-in implementing a simple GUI for the pip command."""
)
needsRestart = False
pyqtApi = 2
python2Compatible = True
# End-Of-Header

error = ""

pipPluginObject = None


def exeDisplayDataList():
    """
    Module function to support the display of some executable info.
    
    @return list of dictionaries containing the data to query the presence of
        the executable
    """
    global pipPluginObject
    
    dataList = []
    data = {
        "programEntry": True,
        "header": QCoreApplication.translate(
            "PipInterfacePlugin", "Package Management - pip"),
        "exe": "dummyExe",
        "versionCommand": "--version",
        "versionStartsWith": "pip",
        "versionPosition": 1,
        "version": "",
        "versionCleanup": None,
        "exeModule": ["-m", "pip"],
    }
    virtualenvManager = e5App().getObject("VirtualEnvManager")
    for venvName in virtualenvManager.getVirtualenvNames():
        interpreter = virtualenvManager.getVirtualenvInterpreter(venvName)
        data["exe"] = interpreter
        dataList.append(data.copy())
    return dataList


def createPipPage(configDlg):
    """
    Module function to create the pip configuration page.
    
    @param configDlg reference to the configuration dialog
    @return reference to the configuration page
    """
    global pipPluginObject
    from UiExtensionPlugins.PipInterface.ConfigurationPage.PipPage import \
        PipPage
    page = PipPage(pipPluginObject)
    return page
    

def getConfigData():
    """
    Module function returning data as required by the configuration dialog.
    
    @return dictionary containing the relevant data
    """
    return {
        "pipPage": [
            QCoreApplication.translate(
                "PipInterfacePlugin", "Python Package Management"),
            "preferences-python.png",
            createPipPage, None, None
        ],
    }


def prepareUninstall():
    """
    Module function to prepare for an un-installation.
    """
    Preferences.Prefs.settings.remove(PipInterfacePlugin.PreferencesKey)


class PipInterfacePlugin(QObject):
    """
    Class implementing the pip interface plug-in.
    
    @signal currentEnvironmentChanged(str) emitted to signal a change of the
        currently selected virtual environment
    """
    PreferencesKey = "PipPlugin"
    
    currentEnvironmentChanged = pyqtSignal(str)
    
    def __init__(self, ui):
        """
        Constructor
        
        @param ui reference to the user interface object (UI.UserInterface)
        """
        super(PipInterfacePlugin, self).__init__(ui)
        self.__ui = ui
        self.__initialize()
        
        self.__defaults = {
            "CurrentEnvironment": "",
            "PipSearchIndex": "",           # used by the search command
        }
    
    def __initialize(self):
        """
        Private slot to (re)initialize the plugin.
        """
        self.__object = None
        
        self.__mainAct = None
        self.__mainMenu = None
    
    def activate(self):
        """
        Public method to activate this plugin.
        
        @return tuple of None and activation status
        @rtype tuple of (None, bool)
        """
        global error
        error = ""     # clear previous error
        
        global pipPluginObject
        pipPluginObject = self
        
        from UiExtensionPlugins.PipInterface.Pip import Pip
        self.__object = Pip(self, self.__ui)
        self.__object.initActions()
        e5App().registerPluginObject("PipGui", self.__object)
        
        menu = self.__ui.getMenu("extras")
        self.__mainMenu = self.__object.initMenu()
        self.__mainAct = menu.addMenu(self.__mainMenu)
        
        return None, True
    
    def deactivate(self):
        """
        Public method to deactivate this plugin.
        """
        e5App().unregisterPluginObject("PipGui")
        
        menu = self.__ui.getMenu("extras")
        menu.removeAction(self.__mainAct)
        self.__mainAct = None
        
        self.__initialize()
    
    def getPreferences(self, key):
        """
        Public method to retrieve the various pip related settings.
        
        @param key the key of the value to get
        @type str
        @return the requested setting
        @rtype any
        """
        return Preferences.Prefs.settings.value(
            self.PreferencesKey + "/" + key, self.__defaults[key])
    
    def setPreferences(self, key, value):
        """
        Public method to store the various pip related settings.
        
        @param key the key of the setting to be set
        @type str
        @param value the value to be set
        @type any
        """
        Preferences.Prefs.settings.setValue(
            self.PreferencesKey + "/" + key, value)
        
        if key == "CurrentEnvironment":
                self.currentEnvironmentChanged.emit(value)
    
    def getMenu(self, name):
        """
        Public method to get a reference to the requested menu.
        
        @param name name of the menu
        @type str
        @return reference to the menu or None, if no
            menu with the given name exists
        @rtype  QMenu or None
        """
        if self.__object is not None:
            return self.__object.getMenu(name)
        else:
            return None
    
    def getMenuNames(self):
        """
        Public method to get the names of all menus.
        
        @return menu names
        @rtype list of str
        """
        if self.__object is not None:
            return list(self.__menus.keys())
        else:
            return []

#
# eflag: noqa = M801
