from parallels.core import messages
import logging

from parallels.core import migrator_config
from parallels.core.actions.base.subscription_action import SubscriptionAction
from parallels.core.actions.utils.logging_properties import LoggingProperties
from parallels.core.checking import Report, Problem, PlainReport
from parallels.core.migrator_config import ActionRunnerType
from parallels.core.utils import migrator_utils
from parallels.core.utils.migration_progress import SubscriptionMigrationStatus

logger = logging.getLogger(__name__)


class PrintSubscriptionStatus(SubscriptionAction):
	def get_description(self):
		return messages.PRINT_SUBSCRIPTION_MIGRATION_STATUS

	def get_failure_message(self, global_context, subscription):
		"""
		:type global_context: parallels.core.global_context.GlobalMigrationContext
		:type subscription: parallels.core.migrated_subscription.MigratedSubscription
		"""
		return messages.FAILED_PRINT_SUBSCRIPTION_MIGRATION_STATUS

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

		:rtype: parallels.core.actions.utils.logging_properties.LoggingProperties
		"""
		return LoggingProperties(info_log=False)

	def filter_subscription(self, global_context, subscription):
		"""
		:type global_context: parallels.core.global_context.GlobalMigrationContext
		:type subscription: parallels.core.migrated_subscription.MigratedSubscription
		"""
		action_runner_type = migrator_config.read_action_runner_type(global_context.config)
		return action_runner_type == ActionRunnerType.BY_SUBSCRIPTION

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

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

		:rtype: bool
		"""
		return False

	def run(self, global_context, subscription):
		"""
		:type global_context: parallels.core.global_context.GlobalMigrationContext
		:type subscription: parallels.core.migrated_subscription.MigratedSubscription
		"""
		safe = global_context.safe
		subscription_report = Report('Subscription', subscription.name)

		# add issues from 'Safe'
		if subscription.name in safe.failed_objects.subscriptions:
			global_context.migrator._add_report_issues(
				subscription_report,
				safe.failed_objects.subscriptions[subscription.name]
			)
		for issue in safe.issues.subscriptions[subscription.name]:
			subscription_report.add_issue_obj(issue)

		# add issues from pre-migration checks
		plain_pre_check_report = PlainReport(
			global_context.pre_check_report, *global_context.migrator._extract_source_objects_info()
		)
		subscription_pre_check_report = plain_pre_check_report.get_subscription_report(
			subscription.model.source, subscription.name
		)
		for issue in subscription_pre_check_report.issues:
			subscription_report.add_issue_obj(issue)

		# if report has no issues - add successful status
		if not subscription_report.has_issues():
			subscription_report.add_issue(
				Problem(
					u'subscription_migr_success', Problem.INFO,
					messages.SUBSCRIPTION_MIGRATED_SUCCESSFULLY),
				u""
			)

		# print report
		report_str = migrator_utils.format_report(
			subscription_report, None, None, show_no_issue_branches=False
		)
		logger.info(messages.SUBSCRIPTION_MIGRATION_FINISHED_HERE_IS_STATUS + u"\n" + report_str)

		# update data in global subscription state object
		subscription_status = global_context.progress.get_subscription(
			subscription.name
		)
		if not subscription_report.has_issues():
			subscription_status.status = SubscriptionMigrationStatus.FINISHED_OK
		elif not subscription_report.has_errors():
			subscription_status.status = SubscriptionMigrationStatus.FINISHED_WARNINGS
		else:
			subscription_status.status = SubscriptionMigrationStatus.FINISHED_ERRORS
