import logging
import posixpath
import os

import parallels.plesks_migrator
from parallels.common.utils import plesk_utils
from parallels.common.actions.base.common_action import CommonAction
from parallels.plesks_migrator.dumper import get_dumper
from parallels.common import MigrationError
from parallels.common.context import log_context
from parallels.plesks_migrator.pmm_agent import PleskXPmmMigrationAgent

logger = logging.getLogger(__name__)

class FetchBackupActionBase(CommonAction):
	def run(self, global_context):
		for source_id in self._get_source_servers(global_context):
			source_server = global_context.conn.get_source_node(source_id)
			backup_filename = global_context.session_files.get_path_to_raw_plesk_backup(source_id)

			if not global_context.options.reload_source_data and os.path.exists(backup_filename):
				logger.info(u"Data files for Plesk '%s' already exist, skip loading", source_id)
			else:
				logger.info(u"Fetch configuration data from Plesk '%s'", source_id)
				with log_context(source_id):
					# PfW doesn't report backup manager as installed component
					# despite it has corresponding sections in UI. So check
					# component presence on Unix only.
					if (not source_server.is_windows() and (
						'psa-backup-manager' not in source_server.plesk_components or
						source_server.plesk_components['psa-backup-manager'].version == 'not_installed'
					)):
						raise MigrationError(u"Plesk Backup Manager is not installed on '%s'" % source_id)

					dumper = get_dumper(
						source_server, global_context.migrator_server,
						self._get_pmm_agent(source_server)
					)
					dumper.create_dump(backup_filename)

	def _get_source_servers(self, global_context):
		raise NotImplementedError()

	def _get_pmm_agent(self, source_server):
		"""Initialize and return PmmMigrationAgentBase.

		Args:
			source_settings:
				Source server settings read from a section of config.ini.
		Returns:
			An instance of PmmMigrationAgentBase.
		"""
		if source_server.is_windows():
			return
		else:
			migrator_pmm_dir = posixpath.join(
				plesk_utils.get_migrator_root_path(parallels.plesks_migrator),
				'extras', 'pmm'
			)
			return PleskXPmmMigrationAgent(
				migrator_pmm_dir, source_server, 
				PleskPMMConfig(source_server.node_settings)
			)

class FetchBackupAction(FetchBackupActionBase):
	def get_description(self):
		return "Fetch configuration data from Plesk servers"

	def _get_source_servers(self, global_context):
		return global_context.conn.get_source_plesks()

class PleskPMMConfig(object):
	def __init__(self, settings):
		self.ip = settings.ip
		self.id = settings.id
		self.is_windows = settings.is_windows
		self.ssh_auth = settings.ssh_auth
		self.session_dir = settings.session_dir
		self.agent_home = os.path.join(self.session_dir, 'agent')
		self.pmm_agent_name = "PleskX"
		self.agent_script_name = 'PleskX.pl'
