from parallels.source.plesk import messages
import logging
import posixpath
import re

from parallels.core.actions.base.subscription_action import SubscriptionAction
from parallels.core.utils.common import replace_str_prefix
from parallels.core.utils import subscription_filter
from parallels.core.utils import plesk_utils

logger = logging.getLogger(__name__)


class FixUnixPermissions(SubscriptionAction):
	"""Fix file ownership for files in domain directory after moving.
	
	If two source panels contain subscriptions with same system user names,
	rename one of users. After content migration, chown directories
	and files for renamed system user.
	"""
	def get_description(self):
		return messages.ACTION_FIX_UNIX_PERMISSIONS_DESCRIPTION

	def get_failure_message(self, global_context, subscription):
		return messages.ACTION_FIX_UNIX_PERMISSIONS_FAILED % subscription.name

	def is_critical(self):
		"""If action is critical or not

		If action is critical and it failed for a subscription, migration tool
		won't run the next operations for the subscription.

		:rtype: bool
		"""
		return False

	def filter_subscription(self, global_context, subscription):
		"""
		:type global_context: parallels.core.global_context.GlobalMigrationContext
		:type subscription: parallels.core.migrated_subscription.MigratedSubscription
		"""
		return subscription_filter.unix_with_virtual_hosting(
			subscription
		)

	def run(self, global_context, subscription):
		"""
		:type global_context: parallels.core.global_context.GlobalMigrationContext
		:type subscription: parallels.core.migrated_subscription.MigratedSubscription
		"""
		source_sysuser_name = subscription.raw_backup.get_phosting_sysuser_name()
		sysuser_name = subscription.converted_backup.get_phosting_sysuser_name()
		target_vhost_dir = posixpath.join(
			subscription.web_target_server.vhosts_dir, 
			subscription.name_idn
		) 
		if sysuser_name is not None and source_sysuser_name != sysuser_name:
			logger.debug(messages.LOG_FIX_FILE_OWNERSHIP_AFTER_MOVING)
			with subscription.web_source_server.runner() as runner_source:
				source_vhost_dir = plesk_utils.get_unix_vhost_dir(runner_source, subscription.name)
				owner_file_string = runner_source.run(
					'/usr/bin/find', [source_vhost_dir, '-printf', '%u:%p\n']
				)
			owner_file_list = filter(None, owner_file_string.split('\n'))
			for line in owner_file_list:
				regex = re.compile("^(.+):(.+)$")
				search_result = regex.findall(line)
				if len(search_result) != 0:
					(owner, file_path) = search_result[0]
					if owner == source_sysuser_name:
						with subscription.web_target_server.runner() as runner_target:
							runner_target.run("/bin/chown", [
								sysuser_name, 
								replace_str_prefix(
									file_path, source_vhost_dir, target_vhost_dir
							)])

		with subscription.web_target_server.runner() as runner_target:
			for site in subscription.converted_backup.iter_domains():
				site_vhost_name = plesk_utils.convert_wildcard_to_path(site.name.encode('idna'))
				self._fix_pd_owner(runner_target, subscription.web_target_server.vhosts_dir, site_vhost_name)

	def _fix_pd_owner(self, runner_target, vhosts_dir, site_vhost_name):
		pd_path = posixpath.join(
				vhosts_dir,
				'system',
				site_vhost_name,
				'pd'
			)
		if runner_target.file_exists(pd_path):
			runner_target.run("/bin/chown", [
				"-R",
				"root:psaserv",
				pd_path
			])
			runner_target.run("/bin/chmod", [
				"-R",
				"640",
				pd_path + "/"
			])
			runner_target.run("/bin/chmod", [
				"750",
				pd_path
			])
