from parallels.core import safe_format
from parallels.core.actions.utils.logging_properties import LoggingProperties
from parallels.core.application.adjuster import Adjuster
from parallels.core.logging import get_logger
from parallels.plesk.source.web import messages
from parallels.plesk.source.web.actions.base.folder import FolderAction

logger = get_logger(__name__)


class AdjustPaths(FolderAction):
    """Adjust file paths
    """

    def get_description(self):
        """Get short description of action as string

        :rtype: str | unicode
        """
        return messages.ACTION_ADJUST_PATHS_DESCRIPTION

    def get_failure_message(self, global_context):
        """Get message for situation when action failed

        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :rtype: str | unicode
        """
        return messages.ACTION_ADJUST_PATHS_FAILURE

    def get_logging_properties(self):
        """Get how action should be logged to migration tools end-user

        :rtype: parallels.core.actions.utils.logging_properties.LoggingProperties
        """
        return LoggingProperties(compound=False)

    def is_critical(self):
        """If action is critical or not

        If action is critical and it failed for a subscription, migration tool
        won't run the next operations for the subscription.

        :rtype: bool
        """
        return False

    def get_failure_message_for_folder(self, global_context, folder):
        """Get message for situation when action failed for specific folder

        :type global_context: parallels.plesk.source.web.global_context.WebGlobalMigrationContext
        :type folder: parallels.plesk.source.web.migrated_folder.MigratedFolder
        :rtype: str | unicode | None
        """
        return safe_format(
            messages.ACTION_ADJUST_PATHS_FAILURE_FOR_FOLDER,
            target_folder=folder.target_path
        )

    def run_for_folder(self, global_context, folder):
        """Run action for single migrated database user

        :type global_context: parallels.plesk.source.web.global_context.WebGlobalMigrationContext
        :type folder: parallels.plesk.source.web.migrated_folder.MigratedFolder
        :rtype: list[parallels.core.reports.model.issue.Issue] | None
        """
        return Adjuster().adjust_paths(
            folder.target_server, self._get_path_mapping(global_context), folder.target_path,
            stop_mark=global_context.stop_mark
        )

    @staticmethod
    def _get_path_mapping(global_context):
        """
        :type global_context: parallels.plesk.source.web.global_context.WebGlobalMigrationContext
        :rtype: dict[str | unicode, str | unicode]
        """
        mapping = {}

        for folder in global_context.list_all_migrated_folders():
            mapping[folder.source_absolute_path] = folder.target_path

        return mapping
