from parallels.core.logging import get_logger
from parallels.core.actions.base.common_action import CommonAction
from parallels.core.reports.model.issue import Issue
from parallels.core.utils.common import ilen
from parallels.core.utils.plesk_utils import get_server_info_with_key, count_subscriptions_and_addon_domains
from parallels.plesk import messages

logger = get_logger(__name__)


class CheckTargetLicenseLimits(CommonAction):
    def get_description(self):
        """
        :rtype: str | unicode
        """
        return messages.ACTION_CHECK_TARGET_LICENSE_LIMIT_DESCRIPTION

    def get_failure_message(self, global_context):
        """
        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :rtype: str | unicode
        """
        return messages.ACTION_CHECK_TARGET_LICENSE_LIMIT_FAILURE

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

        If action is critical and it failed, migration tool completely stops.
        Otherwise it proceeds to the next steps of migrations.

        :rtype: bool
        """
        return False

    def run(self, global_context):
        """
        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :rtype: None
        """
        server_info = get_server_info_with_key(global_context.conn.target.plesk_server)
        target_domains_count = count_subscriptions_and_addon_domains(global_context.conn.target.plesk_server)
        target_domains_limit = int(server_info.key.properties.get('lim_dom', '-1'))
        logger.debug(messages.LOG_DOMAINS_ON_TARGET.format(domains_count=target_domains_count))
        logger.debug(messages.LOG_LICENSE_LIMIT_ON_TARGET.format(domains_count=target_domains_limit))

        if target_domains_limit < 0:
            # Negative means no limit, so this check is not necessary
            return

        existing_subscription_names = {
            subscription.name_canonical for subscription in global_context.target_existing_objects.subscriptions
        }
        migrated_domains_count = sum([
            1 + ilen(subscription.raw_dump.iter_addon_domains())  # subscription + addon domains
            for subscription in global_context.iter_all_subscriptions()
            if subscription.name_canonical not in existing_subscription_names
        ])
        logger.debug(messages.LOG_DOMAINS_ON_SOURCE.format(domains_count=migrated_domains_count))

        if target_domains_count + migrated_domains_count > target_domains_limit:
            global_context.pre_check_report.add_issue(
                'target_license_not_enough_domains',
                Issue.SEVERITY_ERROR,
                messages.NOT_ENOUGH_DOMAINS_IN_LICENSE_ISSUE.format(
                    available=target_domains_limit - target_domains_count,
                    required=migrated_domains_count
                ),
                messages.NOT_ENOUGH_DOMAINS_IN_LICENSE_SOLUTION
            )
