from parallels.core import messages
from parallels.core.actions.base.subscription_backup_action import SubscriptionBackupAction
from parallels.core.actions.utils.logging_properties import LoggingProperties
from parallels.core.utils.common import is_empty, append_once
from parallels.core.utils.config_utils import global_section


class ChangeSubscriptionDocumentRootAction(SubscriptionBackupAction):
    """Change subscription document root if corresponding option in configuration file is set

    This is a special action for customers, who want to change virtual host structure during migration.
    For example, if customer has document root at "public_html" in cPanel, but wants to migrate it to
    "httpdocs" which is the default document root name on Plesk, this action will be used.

    To activate the action, use "target-subscription-www-root" option in "[GLOBAL]" section
    of config.ini file, for example:
    ===========================================================================
    [GLOBAL]
    ...
    target-subscription-www-root: httpdocs
    ...
    ===========================================================================
    """

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

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

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

        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :type subscription: parallels.core.migrated_subscription.MigratedSubscription
        """
        return messages.CHANGE_SUBSCRIPTION_DOCROOT_ACTION_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(info_log=False)

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

        :rtype: bool
        """
        return False

    def _filter_subscription_backup(
        self, global_context, subscription, subscription_backup
    ):
        """
        Check if we should run this action on given subscription or not

        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :type subscription: parallels.core.migrated_subscription.MigratedSubscription
        :type subscription_backup: parallels.core.dump.data_model.Subscription
        """
        new_www_root = global_section(global_context.config).get('target-subscription-www-root')
        return not is_empty(new_www_root) and subscription_backup.is_virtual_hosting

    def _run_subscription_backup(
        self, global_context, subscription, subscription_backup
    ):
        """
        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :type subscription: parallels.core.migrated_subscription.MigratedSubscription
        :type subscription_backup: parallels.core.dump.data_model.Subscription
        """
        new_www_root = global_section(global_context.config).get('target-subscription-www-root')
        old_subscription_www_root = subscription_backup.www_root

        for domain in subscription_backup.iter_domains():
            if domain.www_root == old_subscription_www_root:
                domain.set_www_root(new_www_root)
            else:
                for separator in ('/', '\\'):
                    old_www_root_with_suffix = append_once(old_subscription_www_root, separator)
                    new_www_root_with_suffix = append_once(new_www_root, separator)
                    if domain.www_root.startswith(old_www_root_with_suffix):
                        domain.set_www_root(
                            "".join([
                                new_www_root_with_suffix,
                                domain.www_root[len(old_www_root_with_suffix):]
                            ])
                        )
                        break

        for sysuser in subscription_backup.iter_system_users():
            if sysuser.home is None:
                continue

            if sysuser.home == old_subscription_www_root:
                sysuser.home = new_www_root
            else:
                for separator in ('/', '\\'):
                    old_www_root_with_suffix = append_once(old_subscription_www_root, separator)
                    new_www_root_with_suffix = append_once(new_www_root, separator)
                    if sysuser.home.startswith(old_www_root_with_suffix):
                        sysuser.home = "".join([
                            new_www_root_with_suffix,
                            sysuser.home[len(old_www_root_with_suffix):]
                        ])
                        break
