from parallels.core import messages
import logging
from parallels.core.actions.base.common_action import CommonAction

logger = logging.getLogger(__name__)


class RestoreAuxUsers(CommonAction):
	def get_description(self):
		return messages.ACTION_RESTORE_AUX_USERS

	def get_failure_message(self, global_context):
		return messages.FAILED_TO_RESTORE_AUX_USERS

	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, global_context):
		if self._should_skip_user_creation(auxuser, client, global_context):
			logger.debug(
				messages.SKIPPED_CREATING_AN_EXISTING_AUXUSER + auxuser.login)
			return
		with global_context.safe.try_auxiliary_user(
				client.login, auxuser.login,
				messages.FAILED_CREATE_AUXILIARY_USER_PLESK_API):

			all_subscriptions = {sub.name for sub in global_context.iter_all_subscriptions()}
			if auxuser.subscription_name is not None and auxuser.subscription_name not in all_subscriptions:
				return

			global_context.import_api.create_auxuser(global_context, 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) is not 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
