from parallels.core import safe_format
from parallels.core.logging import get_logger
from parallels.core.utils.file_utils import get_size
from parallels.plesk.source.web import messages
from parallels.plesk.source.web.actions.base.folder import FolderAction
from parallels.plesk.source.web.utils.statistics import safe_calc_data_size

logger = get_logger(__name__)


class CalcFolderDataSize(FolderAction):
    """Calculate transferred data size"""

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

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

    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.FAILED_ACTION_CALC_FOLDER_DATA_SIZE

    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.FAILED_ACTION_CALC_FOLDER_DATA_SIZE_FOR_FOLDER,
            target_folder=folder.target_path
        )

    def filter_action(self, global_context):
        """Check whether we should run this action or not. By default True - action should be executed.

        Arguments:
        - global_context - registry with different objects that reused among different actions

        :type global_context: parallels.plesk.source.web.global_context.WebGlobalMigrationContext
        :rtype: bool
        """
        return global_context.statistics_transfer_site is not None

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

        :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
        """
        with safe_calc_data_size():
            global_context.statistics_transfer_site.folder_size += get_size(folder.target_path)
