import logging

from parallels.core.actions.base.subscription_backup_action import SubscriptionBackupAction
from parallels.core.actions.utils.logging_properties import LoggingProperties
from parallels.core.utils.common.ip import is_ipv4, is_ipv6
from parallels.plesk import messages


logger = logging.getLogger(__name__)


class ChangeNoHostingSubscriptionWebIPsPlesk(SubscriptionBackupAction):
	"""Change web IPs according to subscription's hosting addresses for subscription with virtual hosting

	When subscription on target has no web IPs (has only mail hosting), pleskrestore still needs an IP to
	call Plesk CLI utilities, and tries to figure it out from provided backup; it fails, picking
	one of source server's IPs, with which subscription can't be restored.
	Here we pick a suitable IP for pleskrestore.
	"""

	def get_description(self):
		return messages.CHANGE_NO_VHOSTING_SUBSCRIPTION_WEB_IP_IN_BACKUP

	def get_failure_message(self, global_context, subscription):
		"""
		:type global_context: parallels.core.global_context.GlobalMigrationContext
		:type subscription: parallels.core.migrated_subscription.MigratedSubscription
		"""
		return messages.FAILED_TO_CHANGE_NO_VHOSTING_SUBSCRIPTION_WEB_IP_IN_BACKUP

	def get_logging_properties(self):
		return LoggingProperties(info_log=False)

	def _filter_subscription_backup(self, global_context, subscription, subscription_backup):
		return subscription_backup.hosting_type == 'none'

	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
		"""
		all_target_ips = subscription.panel_target_server.get_all_ips(global_context)
		ip_address_to_type = {ip.ip_address: ip.ip_type for ip in all_target_ips}
		target_ip = global_context.conn.target.main_node_ip

		v4, v6 = subscription.target_public_mail_ipv4, subscription.target_public_mail_ipv6

		if v4 is None and v6 is None:
			# If mail IPs are absent too - fallback to IP speicified in config.ini
			if is_ipv4(target_ip):
				(v4, v6) = (target_ip, None)
			elif is_ipv6(target_ip):
				(v4, v6) = (None, target_ip)

		subscription_backup.change_web_ips([
			(v4, ip_address_to_type.get(v4, 'shared')),
			(v6, ip_address_to_type.get(v6, 'shared'))
		])

		logger.debug(
			messages.LOG_WEB_IPS_SET_TO.format(
				subscription_name=subscription.name,
				ipv4=v4,
				ipv6=v6
			)
		)