"""Provides access to stored IDLE configuration information.

Refer to the comments at the beginning of config-main.def for a description of
the available configuration files and the design implemented to update user
configuration information.  In particular, user configuration choices which
duplicate the defaults will be removed from the user's configuration files,
and if a file becomes empty, it will be deleted.

The contents of the user files may be altered using the Options/Configure IDLE
menu to access the configuration GUI (configDialog.py), or manually.

Throughout this module there is an emphasis on returning useable defaults
when a problem occurs in returning a requested configuration value back to
idle. This is to allow IDLE to continue to function in spite of errors in
the retrieval of config information. When a default is returned instead of
a requested config value, a message is printed to stderr to aid in
configuration problem notification and resolution.
"""
# TODOs added Oct 2014, tjr

import os
import sys

from configparser import ConfigParser

class InvalidConfigType(Exception): pass
class InvalidConfigSet(Exception): pass
class InvalidFgBg(Exception): pass
class InvalidTheme(Exception): pass

class IdleConfParser(ConfigParser):
    """
    A ConfigParser specialised for idle configuration file handling
    """
    def __init__(self, cfgFile, cfgDefaults=None):
        """
        cfgFile - string, fully specified configuration file name
        """
        self.file = cfgFile
        ConfigParser.__init__(self, defaults=cfgDefaults, strict=False)

    def Get(self, section, option, type=None, default=None, raw=False):
        """
        Get an option value for given section/option or return default.
        If type is specified, return as type.
        """
        # TODO Use default as fallback, at least if not None
        # Should also print Warning(file, section, option).
        # Currently may raise ValueError
        if not self.has_option(section, option):
            return default
        if type == 'bool':
            return self.getboolean(section, option)
        elif type == 'int':
            return self.getint(section, option)
        else:
            return self.get(section, option, raw=raw)

    def GetOptionList(self, section):
        "Return a list of options for given section, else []."
        if self.has_section(section):
            return self.options(section)
        else:  #return a default value
            return []

    def Load(self):
        "Load the configuration file from disk."
        self.read(self.file)

class IdleUserConfParser(IdleConfParser):
    """
    IdleConfigParser specialised for user configuration handling.
    """

    def AddSection(self, section):
        "If section doesn't exist, add it."
        if not self.has_section(section):
            self.add_section(section)

    def RemoveEmptySections(self):
        "Remove any sections that have no options."
        for section in self.sections():
            if not self.GetOptionList(section):
                self.remove_section(section)

    def IsEmpty(self):
        "Return True if no sections after removing empty sections."
        self.RemoveEmptySections()
        return not self.sections()

    def RemoveOption(self, section, option):
        """Return True if option is removed from section, else False.

        False if either section does not exist or did not have option.
        """
        if self.has_section(section):
            return self.remove_option(section, option)
        return False

    def SetOption(self, section, option, value):
        """Return True if option is added or changed to value, else False.

        Add section if required.  False means option already had value.
        """
        if self.has_option(section, option):
            if self.get(section, option) == value:
                return False
            else:
                self.set(section, option, value)
                return True
        else:
            if not self.has_section(section):
                self.add_section(section)
            self.set(section, option, value)
            return True

    def RemoveFile(self):
        "Remove user config file self.file from disk if it exists."
        if os.path.exists(self.file):
            os.remove(self.file)

    def Save(self):
        """Update user configuration file.

        Remove empty sections. If resulting config isn't empty, write the file
        to disk. If config is empty, remove the file from disk if it exists.

        """
        if not self.IsEmpty():
            fname = self.file
            try:
                cfgFile = open(fname, 'w')
            except OSError:
                os.unlink(fname)
                cfgFile = open(fname, 'w')
            with cfgFile:
                self.write(cfgFile)
        else:
            self.RemoveFile()

class IdleConf:
    """Hold config parsers for all idle config files in singleton instance.

    Default config files, self.defaultCfg --
        for config_type in self.config_types:
            (idle install dir)/config-{config-type}.def

    User config files, self.userCfg --
        for config_type in self.config_types:
        (user home dir)/.idlerc/config-{config-type}.cfg
    """
    def __init__(self):
        self.config_types = ('main', 'extensions', 'highlight', 'keys')
        self.defaultCfg = {}
        self.userCfg = {}
        self.cfg = {}  # TODO use to select userCfg vs defaultCfg
        self.CreateConfigHandlers()
        self.LoadCfgFiles()


    def CreateConfigHandlers(self):
        "Populate default and user config parser dictionaries."
        #build idle install path
        if __name__ != '__main__': # we were imported
            idleDir=os.path.dirname(__file__)
        else: # we were exec'ed (for testing only)
            idleDir=os.path.abspath(sys.path[0])
        userDir=self.GetUserCfgDir()

        defCfgFiles = {}
        usrCfgFiles = {}
        # TODO eliminate these temporaries by combining loops
        for cfgType in self.config_types: #build config file names
            defCfgFiles[cfgType] = os.path.join(
                    idleDir, 'config-' + cfgType + '.def')
            usrCfgFiles[cfgType] = os.path.join(
                    userDir, 'config-' + cfgType + '.cfg')
        for cfgType in self.config_types: #create config parsers
            self.defaultCfg[cfgType] = IdleConfParser(defCfgFiles[cfgType])
            self.userCfg[cfgType] = IdleUserConfParser(usrCfgFiles[cfgType])

    def GetUserCfgDir(self):
        """Return a filesystem directory for storing user config files.

        Creates it if required.
        """
        cfgDir = '.idlerc'
        userDir = os.path.expanduser('~')
        if userDir != '~': # expanduser() found user home dir
            if not os.path.exists(userDir):
                warn = ('\n Warning: os.path.expanduser("~") points to\n ' +
                        userDir + ',\n but the path does not exist.')
                try:
                    print(warn, file=sys.stderr)
                except OSError:
                    pass
                userDir = '~'
        if userDir == "~": # still no path to home!
            # traditionally IDLE has defaulted to os.getcwd(), is this adequate?
            userDir = os.getcwd()
        userDir = os.path.join(userDir, cfgDir)
        if not os.path.exists(userDir):
            try:
                os.mkdir(userDir)
            except OSError:
                warn = ('\n Warning: unable to create user config directory\n' +
                        userDir + '\n Check path and permissions.\n Exiting!\n')
                print(warn, file=sys.stderr)
                raise SystemExit
        # TODO continue without userDIr instead of exit
        return userDir

    def GetOption(self, configType, section, option, default=None, type=None,
                  warn_on_default=True, raw=False):
        """Return a value for configType section option, or default.

        If type is not None, return a value of that type.  Also pass raw
        to the config parser.  First try to return a valid value
        (including type) from a user configuration. If that fails, try
        the default configuration. If that fails, return default, with a
        default of None.

        Warn if either user or default configurations have an invalid value.
        Warn if default is returned and warn_on_default is True.
        """
        try:
            if self.userCfg[configType].has_option(section, option):
                return self.userCfg[configType].Get(section, option,
                                                    type=type, raw=raw)
        except ValueError:
            warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n'
                       ' invalid %r value for configuration option %r\n'
                       ' from section %r: %r' %
                       (type, option, section,
                       self.userCfg[configType].Get(section, option, raw=raw)))
            try:
                print(warning, file=sys.stderr)
            except OSError:
                pass
        try:
            if self.defaultCfg[configType].has_option(section,option):
                return self.defaultCfg[configType].Get(
                        section, option, type=type, raw=raw)
        except ValueError:
            pass
        #returning default, print warning
        if warn_on_default:
            warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n'
                       ' problem retrieving configuration option %r\n'
                       ' from section %r.\n'
                       ' returning default value: %r' %
                       (option, section, default))
            try:
                print(warning, file=sys.stderr)
            except OSError:
                pass
        return default

    def SetOption(self, configType, section, option, value):
        """Set section option to value in user config file."""
        self.userCfg[configType].SetOption(section, option, value)

    def GetSectionList(self, configSet, configType):
        """Return sections for configSet configType configuration.

        configSet must be either 'user' or 'default'
        configType must be in self.config_types.
        """
        if not (configType in self.config_types):
            raise InvalidConfigType('Invalid configType specified')
        if configSet == 'user':
            cfgParser = self.userCfg[configType]
        elif configSet == 'default':
            cfgParser=self.defaultCfg[configType]
        else:
            raise InvalidConfigSet('Invalid configSet specified')
        return cfgParser.sections()

    def GetHighlight(self, theme, element, fgBg=None):
        """Return individual theme element highlight color(s).

        fgBg - string ('fg' or 'bg') or None.
        If None, return a dictionary containing fg and bg colors with
        keys 'foreground' and 'background'.  Otherwise, only return
        fg or bg color, as specified.  Colors are intended to be
        appropriate for passing to Tkinter in, e.g., a tag_config call).
        """
        if self.defaultCfg['highlight'].has_section(theme):
            themeDict = self.GetThemeDict('default', theme)
        else:
            themeDict = self.GetThemeDict('user', theme)
        fore = themeDict[element + '-foreground']
        if element == 'cursor':  # There is no config value for cursor bg
            back = themeDict['normal-background']
        else:
            back = themeDict[element + '-background']
        highlight = {"foreground": fore, "background": back}
        if not fgBg:  # Return dict of both colors
            return highlight
        else:  # Return specified color only
            if fgBg == 'fg':
                return highlight["foreground"]
            if fgBg == 'bg':
                return highlight["background"]
            else:
                raise InvalidFgBg('Invalid fgBg specified')

    def GetThemeDict(self, type, themeName):
        """Return {option:value} dict for elements in themeName.

        type - string, 'default' or 'user' theme type
        themeName - string, theme name
        Values are loaded over ultimate fallback defaults to guarantee
        that all theme elements are present in a newly created theme.
        """
        if type == 'user':
            cfgParser = self.userCfg['highlight']
        elif type == 'default':
            cfgParser = self.defaultCfg['highlight']
        else:
            raise InvalidTheme('Invalid theme type specified')
        # Provide foreground and background colors for each theme
        # element (other than cursor) even though some values are not
        # yet used by idle, to allow for their use in the future.
        # Default values are generally black and white.
        # TODO copy theme from a class attribute.
        theme ={'normal-foreground':'#000000',
                'normal-background':'#ffffff',
                'keyword-foreground':'#000000',
                'keyword-background':'#ffffff',
                'builtin-foreground':'#000000',
                'builtin-background':'#ffffff',
                'comment-foreground':'#000000',
                'comment-background':'#ffffff',
                'string-foreground':'#000000',
                'string-background':'#ffffff',
                'definition-foreground':'#000000',
                'definition-background':'#ffffff',
                'hilite-foreground':'#000000',
                'hilite-background':'gray',
                'break-foreground':'#ffffff',
                'break-background':'#000000',
                'hit-foreground':'#ffffff',
                'hit-background':'#000000',
                'error-foreground':'#ffffff',
                'error-background':'#000000',
                #cursor (only foreground can be set)
                'cursor-foreground':'#000000',
                #shell window
                'stdout-foreground':'#000000',
                'stdout-background':'#ffffff',
                'stderr-foreground':'#000000',
                'stderr-background':'#ffffff',
                'console-foreground':'#000000',
                'console-background':'#ffffff' }
        for element in theme:
            if not cfgParser.has_option(themeName, element):
                # Print warning that will return a default color
                warning = ('\n Warning: configHandler.IdleConf.GetThemeDict'
                           ' -\n problem retrieving theme element %r'
                           '\n from theme %r.\n'
                           ' returning default color: %r' %
                           (element, themeName, theme[element]))
                try:
                    print(warning, file=sys.stderr)
                except OSError:
                    pass
            theme[element] = cfgParser.Get(
                    themeName, element, default=theme[element])
        return theme

    def CurrentTheme(self):
        "Return the name of the currently active theme."
        return self.GetOption('main', 'Theme', 'name', default='')

    def CurrentKeys(self):
        "Return the name of the currently active key set."
        return self.GetOption('main', 'Keys', 'name', default='')

    def GetExtensions(self, active_only=True, editor_only=False, shell_only=False):
        """Return extensions in default and user config-extensions files.

        If active_only True, only return active (enabled) extensions
        and optionally only editor or shell extensions.
        If active_only False, return all extensions.
        """
        extns = self.RemoveKeyBindNames(
                self.GetSectionList('default', 'extensions'))
        userExtns = self.RemoveKeyBindNames(
                self.GetSectionList('user', 'extensions'))
        for extn in userExtns:
            if extn not in extns: #user has added own extension
                extns.append(extn)
        if active_only:
            activeExtns = []
            for extn in extns:
                if self.GetOption('extensions', extn, 'enable', default=True,
                                  type='bool'):
                    #the extension is enabled
                    if editor_only or shell_only:  # TODO if both, contradictory
                        if editor_only:
                            option = "enable_editor"
                        else:
                            option = "enable_shell"
                        if self.GetOption('extensions', extn,option,
                                          default=True, type='bool',
                                          warn_on_default=False):
                            activeExtns.append(extn)
                    else:
                        activeExtns.append(extn)
            return activeExtns
        else:
            return extns

    def RemoveKeyBindNames(self, extnNameList):
        "Return extnNameList with keybinding section names removed."
        # TODO Easier to return filtered copy with list comp
        names = extnNameList
        kbNameIndicies = []
        for name in names:
            if name.endswith(('_bindings', '_cfgBindings')):
                kbNameIndicies.append(names.index(name))
        kbNameIndicies.sort(reverse=True)
        for index in kbNameIndicies: #delete each keybinding section name
            del(names[index])
        return names

    def GetExtnNameForEvent(self, virtualEvent):
        """Return the name of the extension binding virtualEvent, or None.

        virtualEvent - string, name of the virtual event to test for,
                       without the enclosing '<< >>'
        """
        extName = None
        vEvent = '<<' + virtualEvent + '>>'
        for extn in self.GetExtensions(active_only=0):
            for event in self.GetExtensionKeys(extn):
                if event == vEvent:
                    extName = extn  # TODO return here?
        return extName

    def GetExtensionKeys(self, extensionName):
        """Return dict: {configurable extensionName event : active keybinding}.

        Events come from default config extension_cfgBindings section.
        Keybindings come from GetCurrentKeySet() active key dict,
        where previously used bindings are disabled.
        """
        keysName = extensionName + '_cfgBindings'
        activeKeys = self.GetCurrentKeySet()
        extKeys = {}
        if self.defaultCfg['extensions'].has_section(keysName):
            eventNames = self.defaultCfg['extensions'].GetOptionList(keysName)
            for eventName in eventNames:
                event = '<<' + eventName + '>>'
                binding = activeKeys[event]
                extKeys[event] = binding
        return extKeys

    def __GetRawExtensionKeys(self,extensionName):
        """Return dict {configurable extensionName event : keybinding list}.

        Events come from default config extension_cfgBindings section.
        Keybindings list come from the splitting of GetOption, which
        tries user config before default config.
        """
        keysName = extensionName+'_cfgBindings'
        extKeys = {}
        if self.defaultCfg['extensions'].has_section(keysName):
            eventNames = self.defaultCfg['extensions'].GetOptionList(keysName)
            for eventName in eventNames:
                binding = self.GetOption(
                        'extensions', keysName, eventName, default='').split()
                event = '<<' + eventName + '>>'
                extKeys[event] = binding
        return extKeys

    def GetExtensionBindings(self, extensionName):
        """Return dict {extensionName event : active or defined keybinding}.

        Augment self.GetExtensionKeys(extensionName) with mapping of non-
        configurable events (from default config) to GetOption splits,
        as in self.__GetRawExtensionKeys.
        """
        bindsName = extensionName + '_bindings'
        extBinds = self.GetExtensionKeys(extensionName)
        #add the non-configurable bindings
        if self.defaultCfg['extensions'].has_section(bindsName):
            eventNames = self.defaultCfg['extensions'].GetOptionList(bindsName)
            for eventName in eventNames:
                binding = self.GetOption(
                        'extensions', bindsName, eventName, default='').split()
                event = '<<' + eventName + '>>'
                extBinds[event] = binding

        return extBinds

    def GetKeyBinding(self, keySetName, eventStr):
        """Return the keybinding list for keySetName eventStr.

        keySetName - name of key binding set (config-keys section).
        eventStr - virtual event, including brackets, as in '<<event>>'.
        """
        eventName = eventStr[2:-2] #trim off the angle brackets
        binding = self.GetOption('keys', keySetName, eventName, default='').split()
        return binding

    def GetCurrentKeySet(self):
        "Return CurrentKeys with 'darwin' modifications."
        result = self.GetKeySet(self.CurrentKeys())

        if sys.platform == "darwin":
            # OS X Tk variants do not support the "Alt" keyboard modifier.
            # So replace all keybingings that use "Alt" with ones that
            # use the "Option" keyboard modifier.
            # TODO (Ned?): the "Option" modifier does not work properly for
            #        Cocoa Tk and XQuartz Tk so we should not use it
            #        in default OS X KeySets.
            for k, v in result.items():
                v2 = [ x.replace('<Alt-', '<Option-') for x in v ]
                if v != v2:
                    result[k] = v2

        return result

    def GetKeySet(self, keySetName):
        """Return event-key dict for keySetName core plus active extensions.

        If a binding defined in an extension is already in use, the
        extension binding is disabled by being set to ''
        """
        keySet = self.GetCoreKeys(keySetName)
        activeExtns = self.GetExtensions(active_only=1)
        for extn in activeExtns:
            extKeys = self.__GetRawExtensionKeys(extn)
            if extKeys: #the extension defines keybindings
                for event in extKeys:
                    if extKeys[event] in keySet.values():
                        #the binding is already in use
                        extKeys[event] = '' #disable this binding
                    keySet[event] = extKeys[event] #add binding
        return keySet

    def IsCoreBinding(self, virtualEvent):
        """Return True if the virtual event is one of the core idle key events.

        virtualEvent - string, name of the virtual event to test for,
                       without the enclosing '<< >>'
        """
        return ('<<'+virtualEvent+'>>') in self.GetCoreKeys()

# TODO make keyBindins a file or class attribute used for test above
# and copied in function below

    def GetCoreKeys(self, keySetName=None):
        """Return dict of core virtual-key keybindings for keySetName.

        The default keySetName None corresponds to the keyBindings base
        dict. If keySetName is not None, bindings from the config
        file(s) are loaded _over_ these defaults, so if there is a
        problem getting any core binding there will be an 'ultimate last
        resort fallback' to the CUA-ish bindings defined here.
        """
        keyBindings={
            '<<copy>>': ['<Control-c>', '<Control-C>'],
            '<<cut>>': ['<Control-x>', '<Control-X>'],
            '<<paste>>': ['<Control-v>', '<Control-V>'],
            '<<beginning-of-line>>': ['<Control-a>', '<Home>'],
            '<<center-insert>>': ['<Control-l>'],
            '<<close-all-windows>>': ['<Control-q>'],
            '<<close-window>>': ['<Alt-F4>'],
            '<<do-nothing>>': ['<Control-x>'],
            '<<end-of-file>>': ['<Control-d>'],
            '<<python-docs>>': ['<F1>'],
            '<<python-context-help>>': ['<Shift-F1>'],
            '<<history-next>>': ['<Alt-n>'],
            '<<history-previous>>': ['<Alt-p>'],
            '<<interrupt-execution>>': ['<Control-c>'],
            '<<view-restart>>': ['<F6>'],
            '<<restart-shell>>': ['<Control-F6>'],
            '<<open-class-browser>>': ['<Alt-c>'],
            '<<open-module>>': ['<Alt-m>'],
            '<<open-new-window>>': ['<Control-n>'],
            '<<open-window-from-file>>': ['<Control-o>'],
            '<<plain-newline-and-indent>>': ['<Control-j>'],
            '<<print-window>>': ['<Control-p>'],
            '<<redo>>': ['<Control-y>'],
            '<<remove-selection>>': ['<Escape>'],
            '<<save-copy-of-window-as-file>>': ['<Alt-Shift-S>'],
            '<<save-window-as-file>>': ['<Alt-s>'],
            '<<save-window>>': ['<Control-s>'],
            '<<select-all>>': ['<Alt-a>'],
            '<<toggle-auto-coloring>>': ['<Control-slash>'],
            '<<undo>>': ['<Control-z>'],
            '<<find-again>>': ['<Control-g>', '<F3>'],
            '<<find-in-files>>': ['<Alt-F3>'],
            '<<find-selection>>': ['<Control-F3>'],
            '<<find>>': ['<Control-f>'],
            '<<replace>>': ['<Control-h>'],
            '<<goto-line>>': ['<Alt-g>'],
            '<<smart-backspace>>': ['<Key-BackSpace>'],
            '<<newline-and-indent>>': ['<Key-Return>', '<Key-KP_Enter>'],
            '<<smart-indent>>': ['<Key-Tab>'],
            '<<indent-region>>': ['<Control-Key-bracketright>'],
            '<<dedent-region>>': ['<Control-Key-bracketleft>'],
            '<<comment-region>>': ['<Alt-Key-3>'],
            '<<uncomment-region>>': ['<Alt-Key-4>'],
            '<<tabify-region>>': ['<Alt-Key-5>'],
            '<<untabify-region>>': ['<Alt-Key-6>'],
            '<<toggle-tabs>>': ['<Alt-Key-t>'],
            '<<change-indentwidth>>': ['<Alt-Key-u>'],
            '<<del-word-left>>': ['<Control-Key-BackSpace>'],
            '<<del-word-right>>': ['<Control-Key-Delete>']
            }
        if keySetName:
            for event in keyBindings:
                binding = self.GetKeyBinding(keySetName, event)
                if binding:
                    keyBindings[event] = binding
                else: #we are going to return a default, print warning
                    warning=('\n Warning: configHandler.py - IdleConf.GetCoreKeys'
                               ' -\n problem retrieving key binding for event %r'
                               '\n from key set %r.\n'
                               ' returning default value: %r' %
                               (event, keySetName, keyBindings[event]))
                    try:
                        print(warning, file=sys.stderr)
                    except OSError:
                        pass
        return keyBindings

    def GetExtraHelpSourceList(self, configSet):
        """Return list of extra help sources from a given configSet.

        Valid configSets are 'user' or 'default'.  Return a list of tuples of
        the form (menu_item , path_to_help_file , option), or return the empty
        list.  'option' is the sequence number of the help resource.  'option'
        values determine the position of the menu items on the Help menu,
        therefore the returned list must be sorted by 'option'.

        """
        helpSources = []
        if configSet == 'user':
            cfgParser = self.userCfg['main']
        elif configSet == 'default':
            cfgParser = self.defaultCfg['main']
        else:
            raise InvalidConfigSet('Invalid configSet specified')
        options=cfgParser.GetOptionList('HelpFiles')
        for option in options:
            value=cfgParser.Get('HelpFiles', option, default=';')
            if value.find(';') == -1: #malformed config entry with no ';'
                menuItem = '' #make these empty
                helpPath = '' #so value won't be added to list
            else: #config entry contains ';' as expected
                value=value.split(';')
                menuItem=value[0].strip()
                helpPath=value[1].strip()
            if menuItem and helpPath: #neither are empty strings
                helpSources.append( (menuItem,helpPath,option) )
        helpSources.sort(key=lambda x: x[2])
        return helpSources

    def GetAllExtraHelpSourcesList(self):
        """Return a list of the details of all additional help sources.

        Tuples in the list are those of GetExtraHelpSourceList.
        """
        allHelpSources = (self.GetExtraHelpSourceList('default') +
                self.GetExtraHelpSourceList('user') )
        return allHelpSources

    def LoadCfgFiles(self):
        "Load all configuration files."
        for key in self.defaultCfg:
            self.defaultCfg[key].Load()
            self.userCfg[key].Load() #same keys

    def SaveUserCfgFiles(self):
        "Write all loaded user configuration files to disk."
        for key in self.userCfg:
            self.userCfg[key].Save()


idleConf = IdleConf()

# TODO Revise test output, write expanded unittest
### module test
if __name__ == '__main__':
    def dumpCfg(cfg):
        print('\n', cfg, '\n')
        for key in cfg:
            sections = cfg[key].sections()
            print(key)
            print(sections)
            for section in sections:
                options = cfg[key].options(section)
                print(section)
                print(options)
                for option in options:
                    print(option, '=', cfg[key].Get(section, option))
    dumpCfg(idleConf.defaultCfg)
    dumpCfg(idleConf.userCfg)
    print(idleConf.userCfg['main'].Get('Theme', 'name'))
    #print idleConf.userCfg['highlight'].GetDefHighlight('Foo','normal')
