import logging

from parallels.core.actions.content.web.copy_unix_content_base import SourceWebPathConverter
from parallels.core.actions.content.web.copy_unix_content_base import TargetWebPathConverter
from parallels.core.utils.paths import web_paths
from parallels.plesk.source.custom import messages
from parallels.core.actions.base.subscription_action import SubscriptionAction

from parallels.plesk.source.custom.web_files import CustomPanelWebFiles

logger = logging.getLogger(__name__)


class CustomPanelCopyUnixWebContentLocal(SubscriptionAction):
	"""Put Unix web files that are already on target server to correct locations

	This action is applicable when access to the server was not provided in configuration file, and customer
	has already copied files from the source server to the target server
	"""

	def get_description(self):
		"""Get short description of action as string

		:rtype: str
		"""
		return messages.ACTION_COPY_LOCAL_WEB_FILES

	def get_failure_message(self, global_context, subscription):
		"""Get message for situation when action failed

		:type global_context: parallels.core.global_context.GlobalMigrationContext
		:type subscription: parallels.core.migrated_subscription.MigratedSubscription
		"""
		return messages.FAIL_TO_COPY_LOCAL_WEB_FILES

	def filter_subscription(self, global_context, subscription):
		"""Check if we should run this action on given subscription or not

		:type global_context: parallels.core.global_context.GlobalMigrationContext
		:type subscription: parallels.plesk.source.custom.migrated_subscription.CustomPanelMigratedSubscription
		"""
		return (
			global_context.conn.has_hosting_description_config(subscription.model.source)
			and
			# source web server is not specified, we don't have access to it, so
			# if customer has specified some files to copy, we consider that they all are already
			# on the target server
			subscription.web_source_server is None
			and
			subscription.web_target_server is not None
			and
			not subscription.is_windows
		)

	def run(self, global_context, subscription):
		"""Run action on given subscription

		:type global_context: parallels.core.global_context.GlobalMigrationContext
		:type subscription: parallels.plesk.source.custom.migrated_subscription.CustomPanelMigratedSubscription
		"""
		files = CustomPanelWebFiles().list_files_to_copy(global_context, subscription)
		server = subscription.web_target_server
		for item in files:
			source_path = SourceWebPathConverter().expand(item.source_path, server).rstrip('/') + '/'
			target_path = TargetWebPathConverter().expand(item.target_path, server)
			with server.runner() as runner:
				runner.run(
					u"/usr/bin/rsync",
					[u"--archive"] + [u"--exclude=%s" % ex for ex in item.exclude] + [source_path, target_path]
				)

				# For files in document root, automatically change permissions, so site works and could be changed
				# For other files that is not implemented. Check http://kb.odin.com/en/6572 for details on
				# how to change the permissions if they are wrong.
				if (
					isinstance(item.target_path, (web_paths.WebspaceDocumentRoot or web_paths.SiteDocumentRoot))
					and
					subscription.converted_dump.phosting_sysuser_name is not None
				):
					runner.sh('chown -R {user}:{group} {path}', args=dict(
						user=subscription.converted_dump.phosting_sysuser_name,
						group='psacln',
						path=target_path
					))
					runner.sh('chgrp {group} {path}', args=dict(
						group='psaserv',
						path=target_path
					))
