from parallels.core.logging import get_logger
from parallels.core import messages
from parallels.core.actions.base.common_action import CommonAction
from parallels.core.utils.common import is_empty_iterator
from parallels.core.utils.migrator_utils import format_owner_login
from parallels.core.utils.plesk_utils import is_auxiliary_user_role_exists

logger = get_logger(__name__)


class DeployPanelUserRoles(CommonAction):
    """Create user roles on the target panel."""

    def get_description(self):
        return messages.ACTION_RESTORE_AUX_USER_ROLES

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

    def is_critical(self):
        return False

    def filter_action(self, global_context):
        return not is_empty_iterator(self._iter_panel_user_roles_to_create(global_context))

    def run(self, global_context):
        for panel_user_role, owner in self._iter_panel_user_roles_to_create(global_context):
            with global_context.safe.try_auxiliary_user_role(
                format_owner_login(owner.login),
                panel_user_role.name,
                messages.ACTION_RESTORE_AUX_USER_ROLES_CREATE_FAILED
            ):
                logger.info(messages.ACTION_RESTORE_AUX_USER_ROLES_CREATE.format(
                    panel_user_role_name=panel_user_role.name,
                    owner_username=format_owner_login(owner.login)
                ))
                global_context.hosting_repository.panel_user_role.create(panel_user_role, owner)

    def _iter_panel_user_roles_to_create(self, global_context):
        for owner in global_context.target_model.iter_all_owners():
            for panel_user_role in owner.auxiliary_user_roles:
                if self._is_skip_panel_user_role(panel_user_role, owner, global_context):
                    continue
                yield panel_user_role, owner

    @staticmethod
    def _is_skip_panel_user_role(panel_user_role, owner, global_context):
        if is_auxiliary_user_role_exists(global_context.conn.target.plesk_server, owner.login, panel_user_role.name):
            logger.debug(messages.ACTION_RESTORE_AUX_USER_ROLES_SKIP_EXISTING.format(
                panel_user_role_name=panel_user_role.name,
                owner_username=format_owner_login(owner.login)
            ))
            return True
        return False
