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

# Copyright (C) 2010-2016 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
#
# Python X2Go is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Python X2Go is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

"""\
L{X2GoSessionProfiles} class - managing x2goclient session profiles.

L{X2GoSessionProfiles} is a public API class. Use this class in your Python X2Go based
applications.

"""
__NAME__ = 'x2gosessionprofiles-pylib'

import random

# Python X2Go modules
from x2go.defaults import X2GO_SESSIONPROFILES_CONFIGFILES as _X2GO_SESSIONPROFILES_CONFIGFILES
import x2go.backends.profiles.base as base
import x2go.inifiles as inifiles
import x2go.log as log

class X2GoSessionProfiles(base.X2GoSessionProfiles, inifiles.X2GoIniFile):

    def __init__(self, config_files=_X2GO_SESSIONPROFILES_CONFIGFILES, session_profile_defaults=None, logger=None, loglevel=log.loglevel_DEFAULT, **kwargs):
        """\
        Retrieve X2Go session profiles from a file, typically C{~/.x2goclient/sessions}.

        @param config_files: a list of config file locations, the first file name in this list the user has write access to will be the user configuration file
        @type config_files: C{list}
        @param session_profile_defaults: a default session profile
        @type session_profile_defaults: C{dict}
        @param logger: you can pass an L{X2GoLogger} object to the
            L{x2go.backends.profiles.file.X2GoSessionProfiles} constructor
        @type logger: L{X2GoLogger} instance
        @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be
            constructed with the given loglevel
        @type loglevel: C{int}

        """
        # providing defaults for an X2GoSessionProfiles instance will---in the worst case---override your
        # existing sessions file in your home directory once you write the sessions back to file...
        inifiles.X2GoIniFile.__init__(self, config_files=config_files, logger=logger, loglevel=loglevel)
        base.X2GoSessionProfiles.__init__(self, session_profile_defaults=session_profile_defaults, logger=logger, loglevel=loglevel)

    def get_type(self, section, key):
        """\
        Override the inifile class's get_type method due to the special layout of the session profile
        class.

        @param section: INI file section
        @type section: C{str}
        @param key: key in INI file section
        @type key: C{str}

        @return: the data type of C{key} in C{section}
        @rtype: C{type}

        """
        # we have to handle the get_type method separately...
        return self.get_profile_option_type(key)

    def _populate_session_profiles(self):
        """\
        Populate the set of session profiles by loading the session
        profile configuration from a file in INI format.

        @return: a set of session profiles
        @rtype: C{dict}

        """
        session_profiles = [ p for p in self.iniConfig.sections() if p not in self._non_profile_sections and p != 'none' ]
        _session_profiles_dict = {}
        for session_profile in session_profiles:
            for key, default_value in self.defaultSessionProfile.iteritems():
                if not self.iniConfig.has_option(session_profile, key):
                    self._storeValue(session_profile, key, default_value)
            # update cached meta type session profile information
            self.get_profile_metatype(session_profile)
            _session_profiles_dict[session_profile] = self.get_profile_config(session_profile)

        return _session_profiles_dict

    def _is_mutable(self, profile_id):
        return True

    def _supports_mutable_profiles(self):
        return True

    def _write(self):
        self._write_user_config = self.write_user_config
        return inifiles.X2GoIniFile.write(self)

    def _delete_profile(self, profile_id):
        self.iniConfig.remove_section(profile_id)
        try: del self.session_profiles[profile_id]
        except KeyError: pass

    def _update_value(self, profile_id, option, value):
        self.session_profiles[profile_id][option] = value
        if option == 'host':
            value = ','.join(value)
        self._X2GoIniFile__update_value(profile_id, option, value)

    def _get_profile_parameter(self, profile_id, option, key_type):
        return self.get(profile_id, option, key_type)

    def _get_profile_options(self, profile_id):
        return [ o for o in self.iniConfig.options(profile_id) if o != "none" ]

    def _get_profile_ids(self):
        return [ s for s in self.iniConfig.sections() if s != "none" ]

    def _get_server_hostname(self, profile_id):
        return random.choice(self.get_profile_config(profile_id, 'host'))

    def _get_server_port(self, profile_id):
        return self.get_profile_config(profile_id, 'sshport')
