from parallels.core.global_context import GlobalMigrationContext
from parallels.core.global_context import SourceInfo
from parallels.core.dump import dump
from parallels.core.registry import Registry
from parallels.core.utils.common import cached
from parallels.core.utils.common.threading_utils import execute_once_synchronized_by_args
from parallels.plesk.hosting_description.converter_to_dump import read_hosting_description_file
from parallels.plesk.hosting_description.model import HostingDescriptionModel


class CustomPanelGlobalMigrationContext(GlobalMigrationContext):
    """
    :type agent_pool: parallels.plesk.source.custom.utils.agent_pool.AgentPool
    """
    def __init__(self):
        self.session_files = None
        super(CustomPanelGlobalMigrationContext, self).__init__()
        self.source_has_dns_forwarding = False
        self.hosting_analyzer_enabled = False
        self.post_migration_checks_enabled = False
        self.agent_pool = None

    @execute_once_synchronized_by_args
    def get_hosting_description(self, dump_id):
        """
        :type dump_id: str | unicode
        :rtype: parallels.plesk.hosting_description.model.HostingDescriptionModel
        """
        hosting_description_config = self.conn.get_hosting_description_config(dump_id)
        return HostingDescriptionModel(dump_id, read_hosting_description_file(hosting_description_config))

    def get_primary_sources_info(self):
        """
        :rtype list[parallels.core.global_context.SourceInfo]
        """
        return self._sources_info

    @property
    @cached
    def _sources_info(self):
        """Information about source servers we have

        :rtype list[parallels.core.global_context.SourceInfo]
        """
        return [
            PleskConfigurationDumpInfo(self.conn.get_source_by_id(source_id), dump_path)
            for source_id, dump_path in self.conn.get_plesk_configuration_dump_paths().items()
        ]


class PleskConfigurationDumpInfo(SourceInfo):
    def __init__(self, source, dump_path):
        super(PleskConfigurationDumpInfo, self).__init__(source)
        self._dump_path = dump_path

    @cached
    def load_raw_dump(self):
        """Load full raw dump for this source"""
        return dump.load(
            self._dump_path,
            Registry.get_instance().get_context().migration_list_data
        )

    def load_shallow_dump(self):
        """Load shallow dump for this source

        Shallow dump has high-level data about high-level objects only: list of customers, subscriptions, resellers,
        and so on
        """
        return self.load_raw_dump()

    @property
    def is_windows(self):
        return self.load_raw_dump().is_windows
