from parallels.core.logging import get_logger
from parallels.core.actions.base.reseller_action import ResellerAction
from parallels.core.converter.business_objects.common import SOURCE_TARGET
from parallels.core.utils.common_constants import PLESK_EXTENSION_HOOK_RESELLER, PLESK_EXTENSION_BACKUP_TYPE_RESELLER, \
    PLESK_EXTENSION_HOOK_RESELLER_POST_BACKUP
from parallels.plesk.hosting_repository.model import PleskHostingRepositoryModel
from parallels.plesk.source.plesk import messages
from parallels.plesk.source.plesk.actions.utils import get_target_plesk_server, iter_extensions, \
    is_extensions_supported
from parallels.plesk.source.plesk.actions.deploy.extensions.utils import DeployMessages, ExtensionDeployer

logger = get_logger(__name__)


class DeployExtensionsResellers(ResellerAction):
    def get_description(self):
        return messages.ACTION_DEPLOY_EXTENSIONS_RESELLERS

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

    def is_critical(self):
        return False

    def filter_action(self, global_context):
        return is_extensions_supported(global_context)

    def _get_reseller_failure_message(self, global_context, reseller):
        return messages.ACTION_DEPLOY_EXTENSIONS_RESELLERS_RESELLER_FAILED.format(reseller_username=reseller.login)

    def _run_reseller(self, global_context, reseller):
        """Restore extension data for given reseller in target Plesk

        :type global_context: parallels.plesk.source.plesk.global_context.PleskGlobalMigrationContext
        :type reseller: parallels.core.target_data_model.Reseller
        """
        if reseller.source == SOURCE_TARGET:
            # skip resellers that exists on target Plesk before migration
            return
        target_reseller = global_context.hosting_repository.reseller.get_by_username(reseller.login)
        if target_reseller is None:
            logger.warning(messages.ACTION_DEPLOY_EXTENSIONS_RESELLERS_RESELLER_NOT_EXISTS.format(
                reseller_username=reseller.login
            ))
            # skip resellers that have not been created yet
            return
        target_plesk_server = get_target_plesk_server(global_context)
        for extension, source_plesk_server in iter_extensions(
            global_context,
            filter_hook=[PLESK_EXTENSION_HOOK_RESELLER],
            filter_source_id=[reseller.source]
        ):
            deploy_messages = DeployMessages(
                backup_message=messages.ACTION_DEPLOY_EXTENSIONS_RESELLERS_BACKUP,
                backup_failed_message=messages.ACTION_DEPLOY_EXTENSIONS_RESELLERS_BACKUP_FAILED,
                backup_failed_solution_message=messages.ACTION_DEPLOY_EXTENSIONS_RESELLERS_BACKUP_FAILED_SOLUTION,
                copy_content_message=messages.ACTION_DEPLOY_EXTENSIONS_RESELLERS_COPY_CONTENT,
                copy_content_failed_message=messages.ACTION_DEPLOY_EXTENSIONS_RESELLERS_COPY_CONTENT_FAILED,
                copy_content_failed_solution_message=messages.ACTION_DEPLOY_EXTENSIONS_RESELLERS_COPY_CONTENT_FAILED_SOLUTION,
                clear_backup_temp_data_failed_message=messages.ACTION_DEPLOY_EXTENSIONS_RESELLERS_CLEAR_BACKUP_TEMP_DATA_FAILED,
                restore_message=messages.ACTION_DEPLOY_EXTENSIONS_RESELLERS_RESTORE,
                restore_failed_message=messages.ACTION_DEPLOY_EXTENSIONS_RESELLERS_RESTORE_FAILED,
                restore_failed_solution_message=messages.ACTION_DEPLOY_EXTENSIONS_RESELLERS_RESTORE_FAILED_SOLUTION
            )
            source_hosting_repository = PleskHostingRepositoryModel(source_plesk_server)
            source_reseller = source_hosting_repository.reseller.get_by_username(reseller.login)
            for error_message, solution in ExtensionDeployer(
                global_context,
                global_context.cache_state_controllers.reseller,
                extension,
                PLESK_EXTENSION_BACKUP_TYPE_RESELLER,
                entity_name=reseller.login
            ).deploy(
                deploy_messages,
                source_plesk_server,
                target_plesk_server,
                extension.is_hook_available(PLESK_EXTENSION_HOOK_RESELLER_POST_BACKUP),
                source_entity_id=source_reseller.reseller_id,
                target_entity_id=target_reseller.reseller_id,
            ):
                global_context.safe.fail_reseller(
                    name=reseller.login,
                    error_message=error_message,
                    solution=solution,
                    is_critical=False,
                    omit_logging=True
                )
