from parallels.core.actions.base.common_action import CommonAction
from parallels.core.migration_list.entities.ip_mapping import SubscriptionIPMapping
from parallels.core.utils.common_constants import IP_EXCLUSIVE, IP_SHARED
from parallels.core.utils.ip_utils import IPv4AddressType, IPv6AddressType
from parallels.plesk_multi_server import messages
from parallels.plesk_multi_server.target_data_model import PleskMultiServerTargetSubscriptionData


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

        :rtype: str | unicode
        """
        return messages.ACTION_CONVERT_IPS_AND_NODES_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_CONVERT_IPS_AND_NODES_FAILURE

    def run(self, global_context):
        """Run action on given subscription

        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :rtype: None
        """
        for subscription in global_context.iter_all_subscriptions():
            subscription_mapping = global_context.migration_list_data.subscriptions_mapping[subscription.name]

            subscription.model.target_data = PleskMultiServerTargetSubscriptionData(
                node_ip=subscription_mapping.node_ip,
                ipv4_type=self._convert_migration_list_ip_type(
                    subscription_mapping.ipv4,
                    default=self._convert_source_ip_type(
                        IPv4AddressType().get_type_for_backup_subscription(subscription.raw_dump),
                        default=SubscriptionIPMapping.SHARED
                    )
                ),
                ipv6_type=self._convert_migration_list_ip_type(
                    subscription_mapping.ipv6,
                    default=self._convert_source_ip_type(
                        IPv6AddressType().get_type_for_backup_subscription(subscription.raw_dump),
                        default=None
                    )
                )
            )

    @staticmethod
    def _convert_source_ip_type(source_value, default=None):
        """
        :type source_value: str | unicode | None
        :type default: str | unicode | None
        :rtype: str | unicode | None
        """
        if source_value == IP_EXCLUSIVE:
            return PleskMultiServerTargetSubscriptionData.IP_TYPE_EXCLUSIVE
        elif source_value == IP_SHARED:
            return PleskMultiServerTargetSubscriptionData.IP_TYPE_SHARED
        else:
            return default

    @staticmethod
    def _convert_migration_list_ip_type(migration_list_value, default=None):
        """
        :type migration_list_value: str | unicode | None
        :type default: str | unicode | None
        :rtype: str | unicode | None
        """
        if migration_list_value == SubscriptionIPMapping.SHARED:
            return PleskMultiServerTargetSubscriptionData.IP_TYPE_SHARED
        elif migration_list_value == SubscriptionIPMapping.DEDICATED:
            return PleskMultiServerTargetSubscriptionData.IP_TYPE_EXCLUSIVE
        elif migration_list_value == SubscriptionIPMapping.NONE:
            return None
        else:
            return default
