import logging
from parallels.common.actions.base.common_action import CommonAction

logger = logging.getLogger(__name__)


class RestoreAuxUsers(CommonAction):
	def get_description(self):
		return "Restore auxusers"

	def get_failure_message(self, global_context):
		return "Failed to restore auxusers"

	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 run(self, global_context):
		model = global_context.target_model.model
		for _, target_client in model.clients.items():
			for auxuser in target_client.auxiliary_users:
				self._create_user(auxuser, target_client, global_context)

	def _create_user(self, auxuser, client, context):
		if self._should_skip_user_creation(auxuser, client, context):
			logger.debug(
				"Skipped creating an existing auxuser " + auxuser.login)
			return
		with context.safe.try_auxiliary_user(
				client.login, auxuser.login,
				u"Failed to create auxiliary user with Plesk API."):
			subscription_id = self._get_subscription_id(
				auxuser.subscription_name, context)
			result = context.import_api.create_auxuser(
					auxuser, client, subscription_id)
			report = context.safe.failed_objects
			self._register_result(result, report, client, auxuser)

	def _register_result(self, result, report, client, auxuser):
		if result is not None:
			auxuser_report = report.auxiliary_users[(client.login, auxuser.login)]
			auxuser_report.append(result)

	def _should_skip_user_creation(self, auxuser, client, context):
		return (self._get_existing_auxuser(auxuser, client, context) != None
				or auxuser.login == client.login)

	def _get_subscription_id(self, subscription_name, context):
		'''Get ID of subscription, for which auxuser should have access.
		
		For auxuser that has access to all subscription, '0' is returned.
		
		If subscription ID is found, it is returned. If subscription, for which
		user is granted access, is not included in migration list, its ID
		cannot be found. In that case, auxuser will have access to all
		subscriptions.'''
		ALL_SUBSCRIPTIONS = 0
		if not subscription_name:
			return ALL_SUBSCRIPTIONS
		found_id = context.import_api.get_subscription_id(subscription_name)
		return found_id if found_id is not None else ALL_SUBSCRIPTIONS

	def _get_existing_auxuser(self, auxuser, client, context):
		"""Return an auxuser object if it exists on target panel."""
		existing_auxuser = context.target_existing_objects.auxiliary_users
		if (client.login, auxuser.name) in existing_auxuser:
			return existing_auxuser[(client.login, auxuser.name)]
		else:
			return None
