import logging

from parallels.utils import obj, group_by
from parallels.common.utils import windows_utils, subscription_filter
from parallels.common.actions.content.web.copy_windows_content_base import CopyWindowsWebContentBase
from parallels.common import MigrationError

logger = logging.getLogger(__name__)


class CopyWindowsWebContent(CopyWindowsWebContentBase):
	def __init__(self):
		self._check_source_file_exists = True

	def filter_subscription(self, global_context, subscription):
		if subscription.is_fake:
			if all([not site.is_virtual_hosting for site in subscription.raw_backup.iter_sites()]):
				return False
			else:
				return True
		else:
			return subscription_filter.windows_with_virtual_hosting(
				subscription
			)

	def _list_files_to_copy(self, global_context, subscription):
		vhost_name = subscription.name_idn

		tocopy = []
		exclude = []

		with subscription.web_target_server.runner() as runner_target:
			target_vhosts_dir = subscription.web_target_server.vhosts_dir
			for site in subscription.raw_backup.iter_addon_domains():
				if site.hosting_type != 'phosting':
					continue
				vhost_site_name = site.name.encode('idna')
				tocopy.append(
					obj(
						domain_name = site.name,
						source_filename=vhost_site_name + '/wwwroot/',
						target_filename="%s/httpdocs/%s/" % (
							vhost_name,
							vhost_site_name
						),
						exclude=[],
						# FTP only subscription may have no wwwroot
						skip_if_source_not_exists=True 
					),
				)
				runner_target.mkdir(
					windows_utils.path_join(
						target_vhosts_dir, vhost_name, 'private'
					)
				)
				tocopy.append(
					obj(
						domain_name = site.name,
						source_filename=vhost_site_name,
						target_filename="%s/private/%s/" % (
							vhost_name,
							vhost_site_name
						),
						exclude=['/' + vhost_site_name + '/wwwroot/'],
						skip_if_source_not_exists=False
					),
				)
				exclude.append(vhost_site_name)
			
			if not subscription.is_fake:
				tocopy.append(
					obj(
						domain_name = subscription.name,
						source_filename=vhost_name + '/wwwroot/',
						target_filename="%s/httpdocs/%s" % (vhost_name, vhost_name),
						exclude=exclude,
						# FTP only subscription may have no wwwroot
						skip_if_source_not_exists=True 
					),
				)
				runner_target.mkdir(
					windows_utils.path_join(
						target_vhosts_dir, vhost_name, 'private'
					)
				)
				tocopy.append(
					obj(
						domain_name = subscription.name,
						source_filename=vhost_name,
						target_filename="%s/private/%s" % (vhost_name, vhost_name),
						exclude=['/' + vhost_name + '/wwwroot/', '/' + vhost_name + '/SSL/'],
						skip_if_source_not_exists=False
					),
				)
				source_server = subscription.web_source_server
				with source_server.runner() as runner_source:				
					if windows_utils.file_exists(
						runner_source,	
						windows_utils.path_join(
							global_context.helm3_agent.get_vhosts_dir_source(
								source_server
							),
							vhost_name,
							'SSL'
						)
					):
						runner_target.mkdir(
							windows_utils.path_join(
								target_vhosts_dir, vhost_name, 'httpsdocs'
							)
						)
						tocopy.append(
							obj(
								domain_name = subscription.name,
								source_filename=vhost_name + '/SSL/',
								target_filename="%s/httpsdocs/%s" % (vhost_name, vhost_name),
								exclude=[],
								skip_if_source_not_exists=True
							),
						)

		return tocopy

	def _get_source_vhosts_dir(self, global_context, source_server):
		return global_context.helm3_agent.get_vhosts_dir_source(
			source_server
		)

	def run(self, global_context, subscription):
		list_files = self._list_files_to_copy(global_context, subscription)
		try:
			files_by_domain_name = group_by(
				list_files,
				lambda x: x.domain_name
			)
			for domain_name, files in files_by_domain_name.iteritems():
				source_web_ip = global_context.migrator.get_domain_content_ip(domain_name)
				web_source_server = global_context.conn.helm3.get_source_server_by_ip(source_web_ip)
				self._copy_files_windows(
					global_context,
					subscription,
					files,
					source_web_ip,
					subscription.web_target_server,
					web_source_server
				)
		except Exception as e:
			logger.debug(u"Exception: ", exc_info=e)
			raise MigrationError((
				u"Rsync failed to copy files from the source (%s) to the target server (%s): %s\n"
				u"""This could happen because of a network connection issue. Retry copying the files with the help of the "copy-content" command."""
			) % (
				subscription.web_source_server.description(),
				subscription.web_target_server.description(),
				str(e)
			))
