from parallels.core.actions.base.entry_point_action import EntryPointAction
from parallels.core.actions.hosting_settings.verify_hosting_settings import VerifyHostingSettings
from parallels.core.utils.backup_adapter import SubscriptionBackup
from parallels.core.workflow.extension import WorkflowExtensionBase
from parallels.plesk.actions.adjust_applications import AdjustApplications
from parallels.plesk.actions.apache_restart_interval.restore import RestoreApacheRestartIntervalPlesk
from parallels.plesk.actions.apache_restart_interval.set import SetApacheRestartInterval
from parallels.plesk.actions.check_target_license_limits import CheckTargetLicenseLimits
from parallels.plesk.actions.convert import ConvertAuxUserRoles
from parallels.plesk.actions.convert import ConvertAuxUsers
from parallels.plesk.actions.convert_ip_addresses import ConvertIPAddressesAction
from parallels.plesk.actions.deploy.hosting_plans import DeployHostingPlans
from parallels.plesk.actions.deploy.reseller_plans import DeployResellerPlans
from parallels.plesk.actions.fix_web_confix_dot_net_2_to_4 import FixWebConfigDotNet2To4
from parallels.plesk.actions.hosting_settings.check.check_missing_components import CheckMissingComponents
from parallels.plesk.actions.hosting_settings.convert.change_no_hosting_subscription_web_ips import \
    ChangeNoHostingSubscriptionWebIPsPlesk
from parallels.plesk.actions.hosting_settings.convert.fix_dns_zone_inconsistency import FixDnsZoneInconsistency
from parallels.plesk.actions.hosting_settings.convert.remove_limits_and_permissions import RemoveLimitsAndPermissions
from parallels.plesk.actions.hosting_settings.convert.remove_missing_components import RemoveMissingComponents
from parallels.plesk.actions.hosting_settings.convert.dns import ConvertDns
from parallels.plesk.actions.hosting_settings.reset_hosting_for_nohosting_subscription import \
    ResetHostingForSubscriptionWithoutHosting
from parallels.plesk.actions.hosting_settings.set_customers_external_id import SetCustomersExternalId
from parallels.plesk.actions.hosting_settings.set_resellers_external_id import SetResellersExternalId
from parallels.plesk.actions.hosting_settings.set_subscription_external_id import SetSubscriptionExternalId
from parallels.plesk.actions.print_application_adjust_report import PrintApplicationAdjustReport
from parallels.plesk.actions.sync_subscription_plan import SyncSubscriptionPlan


class WorkflowExtension(WorkflowExtensionBase):
    def extend_workflow(self, workflow):
        """Extend shared hosting workflow with plesk-specific actions

        :type workflow parallels.core.workflow.base_workflow.BaseWorkflow
        """
        # check what Plesk Migrator process executed under privileged system account, it should be done
        # before any operations with target server to ensure what it has enough permissions
        workflow.get_shared_action('initial-pre-checks').insert_action(
            'check-target-account',
            workflow.get_shared_action('check-target-account'),
            before='check-connections'
        )

        workflow.get_path('check/check-data').insert_action(
            'check-target-license-limits', CheckTargetLicenseLimits()
        )
        workflow.get_path('transfer-accounts').insert_action(
            'check-target-license-limits', CheckTargetLicenseLimits(), after='convert-target-model'
        )
        workflow.get_path('transfer-accounts').insert_action(
            'convert-aux-user-roles', ConvertAuxUsers(), after='convert-target-model'
        )
        workflow.get_path('transfer-accounts').insert_action(
            'convert-aux-user-roles', ConvertAuxUserRoles(), after='convert-target-model'
        )

        workflow.get_path('transfer-accounts').insert_action(
            'check-plesk-infrastructure',
            workflow.get_shared_action_pointer('check-infrastructure'),
            before='check-main-node-disk-space-requirements'
        )

        workflow.get_path('transfer-accounts').insert_action(
            'restore-apache-restart-interval', RestoreApacheRestartIntervalPlesk(), after='remove-imported-backups'
        )
        workflow.get_path('transfer-accounts').insert_action(
            'set-apache-restart-interval', SetApacheRestartInterval(), after='check-main-node-disk-space-requirements'
        )
        workflow.get_path('transfer-accounts/restore-hosting').insert_action(
            'reset-hosting-for-subscription-without-hosting',
            ResetHostingForSubscriptionWithoutHosting(), before='restore-hosting-settings'
        )
        workflow.get_path('transfer-accounts').register_shutdown(
            'set-apache-restart-interval',
            'restore-apache-restart-interval'
        )

        workflow.get_shared_action('verify-hosting').insert_action(
            'verify-hosting-settings', VerifyHostingSettings()
        )

        workflow.get_path('check/check-data').insert_action(
            'check-missing-conflicts',
            CheckMissingComponents()
        )
        workflow.get_shared_action('convert-hosting').insert_action(
            'remove-missing-components',
            RemoveMissingComponents(),
            before='save-backup'
        )

        workflow.get_path('transfer-accounts').insert_action(
            'sync-subscription-plan', SyncSubscriptionPlan(), after='copy-content'
        )
        workflow.get_shared_action('convert-hosting').insert_action(
            'convert-dns', ConvertDns(), after='create-converted-backup'
        )
        workflow.get_shared_action('convert-hosting').insert_action(
            'fix-dns-zone-inconsistency', FixDnsZoneInconsistency(), after='convert-dns'
        )
        workflow.get_shared_action('convert-hosting').insert_action(
            'change-no-hosting-subscription-web-ips',
            ChangeNoHostingSubscriptionWebIPsPlesk(SubscriptionBackup()),
            after='change-hosting-subscription-web-ips'
        )
        workflow.get_shared_action('convert-hosting').insert_action(
            'remove-expiration-date',
            RemoveLimitsAndPermissions(SubscriptionBackup()),
            before='save-backup'
        )
        workflow.get_shared_action('copy-web-content').insert_action(
            'adjust-applications', AdjustApplications(), after='web-assets'
        )
        workflow.get_path('transfer-accounts').insert_action(
            'print-application-adjust-report', PrintApplicationAdjustReport(),
            before='print-post-migration-report'
        )
        workflow.get_path('copy-content').insert_action(
            'print-application-adjust-report', PrintApplicationAdjustReport(),
            after='print-subscription-report'
        )
        workflow.get_path('copy-web-content').insert_action(
            'print-application-adjust-report', PrintApplicationAdjustReport(),
            after='print-subscription-report'
        )
        workflow.get_shared_action('sync-web-content-assets').insert_action(
            'fix-web-config-dot-net-2-to-4', FixWebConfigDotNet2To4()
        )

        workflow.get_path('deploy-resellers').insert_action(
            'deploy-reseller-plans', DeployResellerPlans(), before='deploy-resellers'
        )

        workflow.get_shared_action('convert').insert_action(
            'convert-ip-addresses', ConvertIPAddressesAction(), after='convert-clients-and-subscriptions'
        )

        workflow.get_path('transfer-accounts/deploy').insert_action(
            'set-resellers-external-id', SetResellersExternalId(), after='deploy-resellers'
        )
        workflow.get_path('transfer-accounts/deploy').insert_action(
            'set-customers-external-id', SetCustomersExternalId(), after='deploy-customers'
        )
        workflow.get_path('transfer-accounts/deploy').insert_action(
            'set-subscription-external-id', SetSubscriptionExternalId(), after='deploy-subscription'
        )

        self._configure_entry_point_deploy_hosting_plans(workflow)
        self._configure_entry_point_adjust_applications(workflow)
        self._configure_entry_point_set_external_id(workflow)

    @staticmethod
    def _configure_entry_point_deploy_hosting_plans(workflow):
        workflow.replace_entry_point('deploy-hosting-plans', EntryPointAction())
        workflow.get_path('deploy-hosting-plans').insert_action(
            'prepare-assets', workflow.get_shared_action('prepare-assets')
        )
        workflow.get_path('deploy-hosting-plans').insert_action('deploy-hosting-plans', DeployHostingPlans())
        workflow.get_path('deploy-hosting-plans').insert_action(
            'cleanup', workflow.get_shared_action('cleanup')
        )
        workflow.get_path('deploy-hosting-plans').register_overall_shutdown('cleanup')

    @staticmethod
    def _configure_entry_point_adjust_applications(workflow):
        workflow.add_entry_point('adjust-applications', EntryPointAction())
        workflow.get_path('adjust-applications').insert_action(
            'prepare-assets', workflow.get_shared_action('prepare-assets')
        )
        workflow.get_path('adjust-applications').insert_action(
            'adjust-applications', AdjustApplications()
        )
        workflow.get_path('adjust-applications').insert_action(
            'print-application-adjust-report', PrintApplicationAdjustReport()
        )
        workflow.get_path('adjust-applications').insert_action(
            'cleanup', workflow.get_shared_action('cleanup')
        )
        workflow.get_path('adjust-applications').register_overall_shutdown('cleanup')

    @staticmethod
    def _configure_entry_point_set_external_id(workflow):
        workflow.replace_entry_point('set-external-id', EntryPointAction())
        workflow.get_path('set-external-id').insert_action(
            'prepare-assets', workflow.get_shared_action('prepare-assets')
        )
        workflow.get_path('set-external-id').insert_action('set-resellers-external-id', SetResellersExternalId())
        workflow.get_path('set-external-id').insert_action('set-customers-external-id', SetCustomersExternalId())
        workflow.get_path('set-external-id').insert_action('set-subscription-external-id', SetSubscriptionExternalId())
        workflow.get_path('set-external-id').insert_action('cleanup', workflow.get_shared_action('cleanup'))
        workflow.get_path('set-external-id').register_overall_shutdown('cleanup')
