from parallels.core.connections.connections import Connections
from parallels.core.utils.common import cached, is_run_on_windows
from parallels.core.utils.common_constants import SOURCE_DEFAULT_SESSION_DIR, SSH_DEFAULT_PORT
from parallels.core.utils.config_utils import ConfigSection, read_selection_option
from parallels.plesk.source.web.config import WebSourceConfig, TransferFilesModeOption, FileTransportOption, \
    ListFilesModeOption
from parallels.plesk.source.web.source import WebSource


class WebConnections(Connections):
    SOURCE_ID_WEB = 'web'

    def get_source_config(self):
        """Return configuration of default source

        :rtype: parallels.plesk.source.web.config.WebSourceConfig
        """
        return self.get_source_config_by_id(self.SOURCE_ID_WEB)

    def get_source(self):
        """Return default web source object

        :rtype: parallels.plesk.source.web.connections.WebSource
        """
        return self.get_source_by_id(self.SOURCE_ID_WEB)

    @cached
    def get_source_config_by_id(self, source_id):
        """Return configuration of source with given identifier

        :type source_id: str | unicode
        :rtype: parallels.plesk.source.web.config.WebSourceConfig
        """
        config_section = ConfigSection(self._global_context.config, source_id)
        ftp_config_section = config_section.prefixed('ftp-')

        if 'host' in config_section:
            host = config_section.get('host')
        else:  # for compatibility with old migration sessions, where host was specified in "ftp-host" option
            host = ftp_config_section.get('host')

        host = host.decode('utf-8')

        if 'username' in config_section:
            username = config_section.get('username')
        else:  # for compatibility with old migration sessions, where username was specified in "ftp-username" option
            username = ftp_config_section.get('username')

        if 'password' in config_section:
            password = config_section.get_password('password')
        else:  # for compatibility with old migration sessions, where password was specified in "ftp-password" option
            password = ftp_config_section.get_password('password')

        if is_run_on_windows():
            file_transport = FileTransportOption.FTP
        else:
            file_transport = read_selection_option(config_section, FileTransportOption())

        transfer_files_mode = read_selection_option(config_section, TransferFilesModeOption())
        list_files_mode = read_selection_option(config_section, ListFilesModeOption())

        return WebSourceConfig(
            source_id,
            config_section,
            host,
            username,
            password,
            ftp_config_section.get('encoding', 'utf-8'),
            config_section.getint('ssh-port', SSH_DEFAULT_PORT),
            config_section.get('session-dir', SOURCE_DEFAULT_SESSION_DIR),
            config_section.get('base-url'),
            config_section.get('document-root'),
            config_section.get('files-root'),
            config_section.get('target-domain').decode('utf-8'),
            config_section.getboolean('allow-insecure-connections', False),
            file_transport,
            transfer_files_mode,
            config_section.getboolean('allow-auto-web-streaming', False),
            list_files_mode,
            config_section.getboolean('ignore-passive-mode-server-ip', True),
            config_section.getboolean('single-file-web-rpc-agent', True),
        )

    @cached
    def get_source_by_id(self, source_id):
        """Return web source with given identifier

        :type source_id: str | unicode
        :rtype: parallels.plesk.source.web.connections.WebSource
        """
        source_config = self.get_source_config_by_id(source_id)
        return WebSource(source_id, source_config, self._global_context.migrator_server)

    def get_source_servers(self):
        """Get servers which could provide info about subscriptions and customers"""
        return {source.source_id: source.config for source in self.get_sources()}

    @staticmethod
    def iter_database_servers():
        return []

    def get_stats_server(self):
        """Get source panel IP address that will be saved in statistics report

        If we don't know it (for example in case of web migration with absolutely no access
        to the source server) - return None

        :rtype: str | unicode | None
        """
        return None

    def _get_source_config_section_names(self):
        """Get names of sections describing sources of data

        :rtype: list[str | unicode]
        """
        return [self.SOURCE_ID_WEB]
