import logging

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 = logging.getLogger(__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())
		)