from parallels.core.logging import get_logger
from parallels.core.actions.base.customer_action import CustomerAction
from parallels.core.converter.business_objects.common import SOURCE_TARGET
from parallels.core.utils.common_constants import PLESK_EXTENSION_BACKUP_TYPE_CUSTOMER, \
    PLESK_EXTENSION_HOOK_CUSTOMER, PLESK_EXTENSION_HOOK_CUSTOMER_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 DeployExtensionsCustomers(CustomerAction):
    def get_description(self):
        return messages.ACTION_DEPLOY_EXTENSIONS_CUSTOMERS

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

    def is_critical(self):
        return False

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

    def _get_customer_failure_message(self, global_context, customer):
        return messages.ACTION_DEPLOY_EXTENSIONS_CUSTOMERS_CUSTOMER_FAILED.format(customer_username=customer.login)

    def _run_customer(self, global_context, customer, reseller_username=None):
        """Restore extension data for given customer in target Plesk

        :type global_context: parallels.plesk.source.plesk.global_context.PleskGlobalMigrationContext
        :type customer: parallels.core.target_data_model.Client
        :type reseller_username: str | None
        """
        if customer.source == SOURCE_TARGET:
            # skip customers that exists on target Plesk before migration
            return
        target_customer = global_context.hosting_repository.customer.get_by_username(customer.login)
        if target_customer is None:
            logger.warning(messages.ACTION_DEPLOY_EXTENSIONS_CUSTOMERS_CUSTOMER_NOT_EXISTS.format(
                customer_username=customer.login
            ))
            # skip customers 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_CUSTOMER],
            filter_source_id=[customer.source]
        ):
            deploy_messages = DeployMessages(
                backup_message=messages.ACTION_DEPLOY_EXTENSIONS_CUSTOMERS_BACKUP,
                backup_failed_message=messages.ACTION_DEPLOY_EXTENSIONS_CUSTOMERS_BACKUP_FAILED,
                backup_failed_solution_message=messages.ACTION_DEPLOY_EXTENSIONS_CUSTOMERS_BACKUP_FAILED_SOLUTION,
                copy_content_message=messages.ACTION_DEPLOY_EXTENSIONS_CUSTOMERS_COPY_CONTENT,
                copy_content_failed_message=messages.ACTION_DEPLOY_EXTENSIONS_CUSTOMERS_COPY_CONTENT_FAILED,
                copy_content_failed_solution_message=messages.ACTION_DEPLOY_EXTENSIONS_CUSTOMERS_COPY_CONTENT_FAILED_SOLUTION,
                clear_backup_temp_data_failed_message=messages.ACTION_DEPLOY_EXTENSIONS_CUSTOMERS_CLEAR_BACKUP_TEMP_DATA_FAILED,
                restore_message=messages.ACTION_DEPLOY_EXTENSIONS_CUSTOMERS_RESTORE,
                restore_failed_message=messages.ACTION_DEPLOY_EXTENSIONS_CUSTOMERS_RESTORE_FAILED,
                restore_failed_solution_message=messages.ACTION_DEPLOY_EXTENSIONS_CUSTOMERS_RESTORE_FAILED_SOLUTION
            )
            source_hosting_repository = PleskHostingRepositoryModel(source_plesk_server)
            source_customer = source_hosting_repository.customer.get_by_username(customer.login)
            for error_message, solution in ExtensionDeployer(
                global_context,
                global_context.cache_state_controllers.customer,
                extension,
                PLESK_EXTENSION_BACKUP_TYPE_CUSTOMER,
                entity_name=customer.login
            ).deploy(
                deploy_messages,
                source_plesk_server,
                target_plesk_server,
                extension.is_hook_available(PLESK_EXTENSION_HOOK_CUSTOMER_POST_BACKUP),
                source_entity_id=source_customer.customer_id,
                target_entity_id=target_customer.customer_id,
            ):
                global_context.safe.fail_client(
                    reseller_name=reseller_username,
                    name=customer.login,
                    error_message=error_message,
                    solution=solution,
                    is_critical=False,
                    omit_logging=True
                )
