from parallels.core import messages
from parallels.core.actions.base.common_action import CommonAction
from parallels.core.actions.utils.logging_properties import LoggingProperties
from parallels.core.statistics import SessionStatistics
from parallels.core.utils.common import ilen
from parallels.core.utils.migrator_utils import get_version
from parallels.core.utils.os_version import detect_os_version, detect_os_architecture
from parallels.core.utils.plesk_utils import get_subscription_count, get_client_count


class StartSessionStatistics(CommonAction):
    """Initially write session statistics once migration is started

    Here we write all data we have to statistics file - source panel version, OS, number of subscription on
    source and target, and so on
    """
    def get_description(self):
        """Get short description of action as string

        :rtype: str
        """
        return messages.ACTION_START_SESSION_STATISTICS

    def get_failure_message(self, global_context):
        """Get message for situation when action failed

        :type global_context: parallels.core.global_context.GlobalMigrationContext
        """
        return messages.FAILED_ACTION_START_SESSION_STATISTICS

    def is_critical(self):
        """If action is critical or not

        If action is critical and it failed, migration tool won't run the next operations.

        :rtype: bool
        """
        return False

    def get_logging_properties(self):
        """Get how action should be logged to migration tools end-user

        :rtype: parallels.core.actions.utils.logging_properties.LoggingProperties
        """
        # We don't won't to bother anybody with statistics, leave it only in debug.log
        return LoggingProperties(info_log=False)

    def run(self, global_context):
        """
        :type global_context: parallels.core.global_context.GlobalMigrationContext
        """
        source_server = global_context.conn.get_stats_server()

        if source_server is None:
            return

        target_server = global_context.conn.target.plesk_server

        source_os_name, source_os_version = detect_os_version(source_server)
        target_os_name, target_os_version = detect_os_version(target_server)

        source_subscriptions = sum([
            ilen(source_info.load_shallow_dump().iter_all_subscriptions())
            for source_info in global_context.get_sources_info()
        ], 0)
        source_clients = sum([
            ilen(source_info.load_shallow_dump().iter_all_clients())
            for source_info in global_context.get_sources_info()
        ], 0)
        migrated_subscriptions = ilen(global_context.iter_all_subscriptions())
        remigrated_subscriptions = len(
            {s.name for s in global_context.iter_all_subscriptions()} &
            set(global_context.statistics_reporter.get_migrated_subscriptions_list())
        )
        target_subscriptions = get_subscription_count(target_server)
        target_clients = get_client_count(target_server)

        global_context.session_statistics = SessionStatistics(
            migrator_version=get_version(),
            source_server_ip=source_server.ip(),
            target_server_ip=target_server.ip(),
            source_server_type=global_context.source_panel_type,
            target_server_type=global_context.target_panel_type,
            source_os_name=source_os_name,
            source_os_version=source_os_version,
            source_os_architecture=detect_os_architecture(source_server),
            target_os_name=target_os_name,
            target_os_version=target_os_version,
            target_os_architecture=detect_os_architecture(target_server),
            source_panel_version=global_context.conn.get_panel_version(),
            target_panel_version=target_server.plesk_version,
            subscriptions_on_target=target_subscriptions,
            subscriptions_on_source=source_subscriptions,
            migrated_subscriptions=migrated_subscriptions,
            remigrated_subscriptions=remigrated_subscriptions,
            clients_on_source=source_clients,
            clients_on_target=target_clients,
            start_time=int(global_context.start_time)
        )

        global_context.statistics_reporter.save_session_statistics(global_context.session_statistics)
