from parallels.core.logging import get_logger
from parallels.core import messages
from parallels.core.actions.base.common_action import CommonAction
from parallels.core.utils.ip_utils import get_ip_address_types
from parallels.core.utils.json_utils import write_json

logger = get_logger(__name__)


class ListIPAddresses(CommonAction):
    """Save source IP addresses list to a file

    Necessary for Plesk UI integration. Writes JSON file to {session_dir}/ips-list.json
    Example contents:
    [
        {"protocol": "ipv4", "type": "shared", "address": "10.52.78.38"},
        {"protocol": "ipv6", "type": "shared", "address": "2002:5bcc:18fd:c:10:52:78:38"}
    ]

    You are required to run 'panel-transfer check' before running this action, and check should pass,
    so we have the following items:
    - converted subscriptions model
    - full raw backup fetched
    """
    def get_description(self):
        return messages.LIST_IP_ADDRESSES_ACTION_DESCRIPTION

    def get_failure_message(self, global_context):
        """
        :type global_context: parallels.core.global_context.GlobalMigrationContext
        """
        return messages.LIST_IP_ADDRESSES_ACTION_FAILURE

    def run(self, global_context):
        """
        :type global_context: parallels.core.global_context.GlobalMigrationContext
        """
        ips_list = []
        added_ips = set()

        for subscription in global_context.iter_all_subscriptions():
            for ip_address_type in get_ip_address_types():
                ip_address = ip_address_type.get_for_backup_subscription(subscription.raw_dump)
                ip_type = ip_address_type.get_type_for_backup_subscription(subscription.raw_dump)
                if ip_address is not None and ip_address not in added_ips:
                    ips_list.append({
                        'address': ip_address,
                        'type': ip_type,
                        'protocol': ip_address_type.title.lower()
                    })
                    added_ips.add(ip_address)

        write_json(global_context.session_files.get_path_to_ips_list(), ips_list)
        logger.info(
            messages.IP_ADDRESSES_LIST_SAVED_TO.format(filename=global_context.session_files.get_path_to_ips_list())
        )