from parallels.source.custom import messages
import logging

from parallels.core.actions.content.web.copy_unix_content_base import CopyWebContentItem
from parallels.core.utils.paths import web_paths
from parallels.source.custom.backup_creator import read_light_backup
from parallels.source.plesk.actions.content.web.copy_unix_content import CopyUnixWebContentBase
from parallels.core.utils.common import find_only, append_if_not_none, is_string


logger = logging.getLogger(__name__)


class CustomPanelCopyUnixWebContent(CopyUnixWebContentBase):
	def filter_subscription(self, global_context, subscription):
		return (
			super(CustomPanelCopyUnixWebContent, self).filter_subscription(global_context, subscription)
			and
			global_context.conn.has_source_light_backup_config(subscription.model.source)
		)

	def _list_files_to_copy(self, global_context, subscription):
		"""Make a list of source server directories and files to be transferred.

		Return:
			A list of (source directory -> destination directory) mappings

		:type global_context: parallels.core.global_context.GlobalMigrationContext
		:type subscription: parallels.source.custom.migrated_subscription.CustomPanelMigratedSubscription
		:rtype: list[parallels.core.actions.content.web.copy_unix_content_base.CopyWebContentItem]
		"""
		tocopy = []

		light_backup_config = global_context.conn.get_source_light_backup_config(subscription.model.source)
		light_backup_data = read_light_backup(light_backup_config)
		subscription_data = self._get_subscription_light_backup_data(light_backup_data, subscription.name)

		append_if_not_none(tocopy, self._convert_light_backup_items(
			subscription.light_backup.source_document_root,
			web_paths.WebspaceDocumentRoot(subscription.converted_backup)
		))
		append_if_not_none(tocopy, self._convert_light_backup_items(
			subscription.light_backup.source_webspace_root,
			web_paths.WebspaceRoot(subscription.converted_backup)
		))

		for web_files_to_copy in subscription_data.get('web_files', []):
			tocopy.append(CopyWebContentItem(
				source_path=web_paths.AbsolutePath(web_files_to_copy['source']),
				target_path=web_paths.WebspacePathTemplate(
					subscription.converted_backup,
					web_files_to_copy['target']
				),
				exclude=web_files_to_copy.get('exclude', []),
				skip_if_source_not_exists=web_files_to_copy.get('skip_if_source_not_exists', False)
			))

		for addon_domain in subscription.converted_backup.iter_addon_domains():
			addon_domnain_light_backup = subscription.light_backup.get_addon_domain(addon_domain.name)
			append_if_not_none(tocopy, self._convert_light_backup_items(
				addon_domnain_light_backup.source_document_root,
				web_paths.SiteDocumentRoot(subscription.converted_backup, addon_domain)
			))

			for addon_domain_web_files_to_copy in addon_domnain_light_backup.iter_web_files():
				tocopy.append(CopyWebContentItem(
					source_path=web_paths.AbsolutePath(addon_domain_web_files_to_copy.source),
					target_path=web_paths.SitePathTemplate(
						subscription.converted_backup,
						addon_domain,
						addon_domain_web_files_to_copy.target
					),
					exclude=addon_domain_web_files_to_copy.exclude,
					skip_if_source_not_exists=addon_domain_web_files_to_copy.skip_if_source_not_exists
				))

		for subdomain in subscription.converted_backup.iter_all_subdomains():
			subdomain_light_backup = subscription.light_backup.get_subdomain(subdomain.name)
			append_if_not_none(tocopy, self._convert_light_backup_items(
				subdomain_light_backup.source_document_root,
				web_paths.SiteDocumentRoot(subscription.converted_backup, subdomain)
			))

			for subdomain_web_files_to_copy in subdomain_light_backup.iter_web_files():
				tocopy.append(CopyWebContentItem(
					source_path=web_paths.AbsolutePath(subdomain_web_files_to_copy.source),
					target_path=web_paths.SitePathTemplate(
						subscription.converted_backup,
						subdomain,
						subdomain_web_files_to_copy.target
					),
					exclude=subdomain_web_files_to_copy.exclude,
					skip_if_source_not_exists=subdomain_web_files_to_copy.skip_if_source_not_exists
				))

		return tocopy

	@staticmethod
	def _convert_light_backup_items(source_value, target_path):
		if source_value is not None:
			if is_string(source_value):
				return CopyWebContentItem(
					source_path=web_paths.AbsolutePath(source_value),
					target_path=target_path
				)
			else:
				return CopyWebContentItem(
					source_path=web_paths.AbsolutePath(source_value['path']),
					target_path=target_path,
					exclude=source_value.get('exclude', [])
				)
		else:
			return None

	@staticmethod
	def _get_subscription_light_backup_data(light_backup_data, subscription_name):
		all_subscriptions = [
			subscription for client in light_backup_data
			for subscription in client.get('subscriptions', [])
		]
		return find_only(
			all_subscriptions, lambda s: s.get('name') == subscription_name,
			messages.FAILED_TO_FIND_SUBSCRIPTION_IN_DUMP % subscription_name
		)
