from parallels.core.actions.base.entry_point_action import EntryPointAction
from parallels.core.workflow.base_workflow import BaseWorkflow
from parallels.core.workflow.builder import WorkflowBuilderBase
from parallels.core.workflow.extension import WorkflowExtensionBase
from parallels.plesk.source.mail.actions.copy_mail_messages import CopyMailMessages
from parallels.plesk.source.mail.actions.deploy_mailboxes import DeployMailboxes
from parallels.plesk.source.mail.actions.read_migration_list import ReadMigrationList
from parallels.plesk.source.mail.actions.refresh_disk_usage import RefreshDiskUsage
from parallels.plesk.source.mail.actions.retrieve_target_site_info import RetrieveTargetSiteInfo
from parallels.plesk.source.mail.actions.write_initial_status import WriteInitialStatus
from parallels.plesk.source.mail.actions.task_manager.add_tasks import AddTasksAction
from parallels.plesk.source.mail.actions.task_manager.cancel_tasks import CancelTasksAction
from parallels.plesk.source.mail.actions.task_manager.run_tasks import RunTasksAction
from parallels.plesk.source.mail.actions.write_final_status import WriteFinalStatus
from parallels.plesk.source.mail.actions.statistics.finalize_transfer_mail import FinalizeTransferMailStatistics
from parallels.plesk.source.mail.actions.statistics.start_transfer_mail import StartTransferMailStatistics


class WorkflowBuilder(WorkflowBuilderBase):
    def create_workflow(self, global_context):
        """Create and return workflow object according given context

        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :rtype: parallels.core.workflow.base_workflow.BaseWorkflow
        """
        workflow = BaseWorkflow()
        WorkflowExtension().extend_workflow(workflow)
        return workflow


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

        :type workflow: parallels.core.workflow.base_workflow.BaseWorkflow
        """
        # 1) Transfer mail command.
        workflow.add_entry_point('transfer-mail', EntryPointAction())
        workflow.get_path('transfer-mail').insert_action(
            'retrieve-target-site-info', RetrieveTargetSiteInfo()
        )
        workflow.get_path('transfer-mail').insert_action(
            'read-migration-list', ReadMigrationList()
        )
        workflow.get_path('transfer-mail').insert_action(
            'start-migration', WriteInitialStatus()
        )
        workflow.get_path('transfer-mail').insert_action(
            'start-transfer-mail-statistics', StartTransferMailStatistics()
        )
        workflow.get_path('transfer-mail').insert_action(
            'deploy-mailboxes', DeployMailboxes()
        )
        workflow.get_path('transfer-mail').insert_action(
            'copy-mail-messages', CopyMailMessages()
        )
        workflow.get_path('transfer-mail').insert_action(
            'refresh-disk-usage', RefreshDiskUsage()
        )
        workflow.get_path('transfer-mail').insert_action(
            'finish-migration', WriteFinalStatus()
        )
        workflow.get_path('transfer-mail').insert_action(
            'finalize-transfer-mail-statistics', FinalizeTransferMailStatistics()
        )
        workflow.get_path('transfer-mail').register_overall_shutdown('finish-migration')
        workflow.get_path('transfer-mail').register_overall_shutdown('finalize-transfer-mail-statistics')

        # 2) Task manager commands: add, cancel and run mail migration tasks.
        # These commands are necessary for asynchronous integration with GUI.
        workflow.add_entry_point('run-mail-migration-tasks', EntryPointAction())
        workflow.get_path('run-mail-migration-tasks').insert_action('run-tasks', RunTasksAction())
        workflow.add_entry_point('add-mail-migration-tasks', EntryPointAction())
        workflow.get_path('add-mail-migration-tasks').insert_action('add-tasks', AddTasksAction())
        workflow.add_entry_point('cancel-mail-migration-tasks', EntryPointAction())
        workflow.get_path('cancel-mail-migration-tasks').insert_action('cancel-tasks', CancelTasksAction())
