from parallels.core import messages, MigrationNoContextError
from parallels.core.actions.base.common_action import CommonAction
from parallels.core.logging import subscription_context
from parallels.core.registry import Registry
from parallels.core.reports.printer import print_report
from parallels.core.utils.migrator_utils import is_running_from_cli


class CheckConvertReportAction(CommonAction):
    def get_description(self):
        """Get short description of action as string

        :rtype: str | unicode
        """
        return messages.ACTION_CHECK_CONVERT_REPORT_DESCRIPTION

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

        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :rtype: str | unicode
        """
        return messages.ACTION_CHECK_CONVERT_REPORT_FAILURE

    def run(self, global_context):
        """Run action

        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :rtype: None
        """
        if (
            not global_context.options.ignore_pre_migration_errors and
            # For pre-migration checks, try to continue and perform as many checks as possible
            Registry.get_instance().get_command_name() != 'check' and
            # Stop migration only when interacting with customer with CLI.
            # For GUI there is pre-migration report, and if customer has skipped errors there, then
            # we should try to migrate anyway. Skipping errors at pre-migration checks screen is logically
            # equivalent to '--ignore-pre-migration-errors' command line option.
            is_running_from_cli()
        ):
            # stop migration if there is any tree issue at the 'error' level
            if global_context.convert_report.has_errors():
                print_report(global_context.convert_report, "convert_report_tree", show_no_issue_branches=False)
                raise MigrationNoContextError(
                    messages.UNABLE_CONTINUE_MIGRATION_UNTIL_THERE_ARE + "\n" +
                    messages.REVIEW_PRE_MIGRATION_ISSUES
                )

        # in the most cases no need to place pre-migration and conversion messages into final report;
        # such messages are matter only for commands related to pre-migration activities or
        # migration itself: 'check' and 'transfer-accounts'
        if Registry.get_instance().get_command_name() in ['check', 'transfer-accounts']:
            # merge pre-migration check tree into final report tree
            for issue in global_context.convert_report.issues:
                # insert conversion issues into pre-migration report
                global_context.pre_check_report.add_issue_obj(issue)
                # insert conversion issues into final report
                global_context.safe.fail_general(issue.problem_text, issue.solution_text, issue.severity)

            for server_id, raw_dump in global_context.migrator.iter_panel_server_raw_dumps():
                for subscription, report in global_context.migrator._iter_subscriptions_by_report_tree(
                    raw_dump, global_context.convert_report
                ):
                    with subscription_context(subscription.name):
                        for issue in report.issues:
                            global_context.safe.add_issue_subscription(subscription.name, issue)

            for subscription in global_context.iter_all_subscriptions():
                convert_report = subscription.get_report(global_context.convert_report)
                pre_check_report = subscription.get_report(global_context.pre_check_report)

                for issue in convert_report.issues:
                    # insert subscription conversion issues into pre-migration report
                    pre_check_report.add_issue_obj(issue)
                    # insert subscription conversion issues into final report
                    global_context.safe.add_issue_subscription(subscription.name, issue)
