import time

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.reports.plain_report import PlainReport
from parallels.core.statistics import SubscriptionStatus


class FinalizeSessionStatistics(CommonAction):
    """Update session statistics once migration is finished

    At this action, we count failed and successful subscriptions count, and update subscription statuses in
    statistics file.
    """
    def get_description(self):
        """Get short description of action as string

        :rtype: str
        """
        return messages.ACTION_FINALIZE_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_FINALIZE_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
        """
        if global_context.session_statistics is None:
            # Skip this action if start statistics session action did not worked
            return

        failed_subscriptions_count = 0
        failed_remigrated_subscriptions_count = 0
        warning_subscriptions_count = 0
        warning_remigrated_subscriptions_count = 0

        plain_report = PlainReport(
            global_context.execution_migration_report, global_context.migration_list_data
        )

        unfiltered_model = global_context.migrator.get_target_model(False)
        already_migrated_subscriptions = set(global_context.statistics_reporter.get_migrated_subscriptions_list())

        for subscription in unfiltered_model.iter_all_subscriptions():
            subscription_report = plain_report.get_subscription_report(subscription.name)

            if subscription_report.has_errors():
                failed_subscriptions_count += 1
                if subscription in already_migrated_subscriptions:
                    failed_remigrated_subscriptions_count += 1
                global_context.statistics_reporter.set_subscription_status(
                    subscription.name, SubscriptionStatus.FAILED
                )
            elif subscription_report.has_warnings():
                warning_subscriptions_count += 1
                if subscription in already_migrated_subscriptions:
                    warning_remigrated_subscriptions_count += 1
                global_context.statistics_reporter.set_subscription_status(
                    subscription.name, SubscriptionStatus.WARNING
                )
            else:
                global_context.statistics_reporter.set_subscription_status(
                    subscription.name, SubscriptionStatus.SUCCESS
                )

        # Write statuses of subscriptions
        global_context.statistics_reporter.write()

        # Update session data
        session_stats = global_context.session_statistics
        session_stats.end_time = int(time.time())
        session_stats.warning_subscriptions = warning_subscriptions_count
        session_stats.warning_remigrated_subscriptions = warning_remigrated_subscriptions_count
        session_stats.failed_subscriptions = failed_subscriptions_count
        session_stats.failed_remigrated_subscriptions = failed_remigrated_subscriptions_count
        session_stats.finished = True

        global_context.statistics_reporter.save_session_statistics(session_stats)