from parallels.core.actions.content.web.copy_unix_content_base import CopyWebContentItem
from parallels.core.utils.paths import web_paths
from parallels.source.plesk.actions.content.web.copy_unix_content import CopyUnixWebContentBase


class PPCPLCopyUnixWebContent(CopyUnixWebContentBase):
	def _list_files_to_copy(self, global_context, subscription):
		"""List web files to copy from the source to the target server

		:type global_context: parallels.core.global_context.GlobalMigrationContext
		:type subscription: parallels.core.migrated_subscription.MigratedSubscription
		:rtype: list[parallels.core.actions.content.web.copy_unix_content_base.CopyWebContentItem]
		"""
		return \
			self._list_main_domain_web_files_to_copy(global_context, subscription) + \
			self._list_subdomain_files_to_copy(global_context, subscription) + \
			self._list_anonftp_files_to_copy(subscription) + \
			self._list_webuser_files_to_copy(subscription)

	def _list_main_domain_web_files_to_copy(self, global_context, subscription):
		"""List httpdocs files of main domain - www-root and cgi-bin

		:rtype: list[parallels.core.actions.content.web.copy_unix_content_base.CopyWebContentItem]
		"""
		tocopy = []

		vhost_name = subscription.name.encode('idna')
		ppcpl_vhost_fs_root = self._get_domain_filesystem_root(vhost_name)

		source_www_root = '%s/var/www/html' % ppcpl_vhost_fs_root

		tocopy.append(
			CopyWebContentItem(
				source_path=web_paths.AbsolutePath(source_www_root),
				target_path=web_paths.WebspaceDocumentRoot(subscription.converted_backup),
				exclude=self._get_htaccess_files_to_exclude(global_context, source_www_root),
				skip_if_source_not_exists=False
			),
		)

		source_cgi_root = '%s/var/www/cgi-bin' % ppcpl_vhost_fs_root

		tocopy.append(
			CopyWebContentItem(
				source_path=web_paths.AbsolutePath(source_cgi_root),
				target_path=web_paths.WebspaceCGIBin(subscription.converted_backup),
				exclude=self._get_htaccess_files_to_exclude(global_context, source_cgi_root),
				skip_if_source_not_exists=True
			)
		)

		return tocopy

	def _list_subdomain_files_to_copy(self, global_context, subscription):
		"""List httpdocs files of all subdomains - www-root and cgi-bin to copy

		:rtype: list[parallels.core.actions.content.web.copy_unix_content_base.CopyWebContentItem]
		"""
		tocopy = []

		vhost_name = subscription.name.encode('idna')
		ppcpl_vhost_fs_root = self._get_domain_filesystem_root(vhost_name)

		subdomain_dirs = global_context.pmm_agent.get_domain_subdomain_dirs(subscription.name)
		for subdomain in subscription.converted_backup.iter_subdomains():
			# note that subdomains don't have protected directories management
			# so there is no need to exclude .htaccess files like we exclude
			# them for domains
			subdomain_www_root, subdomain_cgi_root = subdomain_dirs[
				subdomain.short_name
			]
			tocopy.append(
				CopyWebContentItem(
					source_path=web_paths.AbsolutePath(
						'%s/%s' % (ppcpl_vhost_fs_root, subdomain_www_root)
					),
					target_path=web_paths.SiteDocumentRoot(subscription.converted_backup, subdomain),
					skip_if_source_not_exists=True
				),
			)

			if subdomain_cgi_root != '':
				tocopy.append(
					CopyWebContentItem(
						source_path=web_paths.AbsolutePath(
							'%s/%s' % (ppcpl_vhost_fs_root, subdomain_cgi_root)
						),
						target_path=web_paths.SiteCGIBin(subscription.converted_backup, subdomain),
						skip_if_source_not_exists=True
					),
				)

		return tocopy

	def _list_anonftp_files_to_copy(self, subscription):
		"""
		:rtype: list[parallels.core.actions.content.web.copy_unix_content_base.CopyWebContentItem]
		"""
		tocopy = []

		vhost_name = subscription.name.encode('idna')
		ppcpl_vhost_fs_root = self._get_domain_filesystem_root(vhost_name)

		if subscription.raw_backup.anonftp_enabled:
			tocopy.append(
				CopyWebContentItem(
					source_path=web_paths.AbsolutePath('%s/var/ftp/pub' % ppcpl_vhost_fs_root),
					target_path=web_paths.WebspaceAnonFTPPub(subscription.converted_backup),
					skip_if_source_not_exists=True,
				)
			)

			tocopy.append(
				CopyWebContentItem(
					source_path=web_paths.AbsolutePath('%s/var/ftp/uploads' % ppcpl_vhost_fs_root),
					target_path=web_paths.WebspaceAnonFTPIncoming(subscription.converted_backup),
					skip_if_source_not_exists=True,
				)
			)

		return tocopy

	def _list_webuser_files_to_copy(self, subscription):
		"""
		:rtype: list[parallels.core.actions.content.web.copy_unix_content_base.CopyWebContentItem]
		"""
		tocopy = []

		vhost_name = subscription.name.encode('idna')
		ppcpl_vhost_fs_root = self._get_domain_filesystem_root(vhost_name)

		for webuser_name in subscription.raw_backup.get_phosting_webuser_names():
			tocopy.append(
				CopyWebContentItem(
					source_path=web_paths.AbsolutePath(
						'%s/home/%s/public_html' % (ppcpl_vhost_fs_root, webuser_name)
					),
					target_path=web_paths.WebspaceWebUser(subscription.converted_backup, webuser_name),
					skip_if_source_not_exists=True,
				)
			)
		return tocopy

	@staticmethod
	def _get_htaccess_files_to_exclude(global_context, path):
		"""Get list of .htaccess files that should not be copied to target node

		In PPCPL, a .htaccess file becomes owned by root after site admin
		protects appropriate directory using CP. Such protected directories we
		report to Plesk separately. If we don't exclude them here, Plesk can
		have problems importing such site - unable to remove these .htaccess
		files at restoration stage.
		"""
		with global_context.conn.ppcpl.runner() as runner:
			output = runner.sh(
				'find {path} -name .htaccess -type f -user root '
				'-printf "%P\n"',
				dict(path=path)
			).strip()
			if output == '':
				# split returns list of one empty string, 
				# if source string was empty, so handle this situation
				return []
			else:
				return output.split("\n")

	@staticmethod
	def _get_domain_filesystem_root(domain):
		"""Get full path to domain's filesystem root on PPCPL server

		This is the main location of all domain files.
		"""
		return '/home/virtual/%s' % (domain,)
