import logging
import posixpath

from parallels.common.content.mail.rsync import CopyMailRsync
from parallels.common.content.mail.rsync import TargetMailboxDirectory
from parallels.common.content.mail.rsync import SourceMailDirectory
from parallels.common.content.mail.imapsync import CopyMailImapsync
from parallels.common.content.mail.psamailbackup import CopyMailPsaMailBackup
from parallels.common.migrator_config import MailContent

logger = logging.getLogger(__name__)

class PleskCopyMailContent(object):
	def __init__(self, get_rsync, use_psamailbackup):
		self._get_rsync = get_rsync
		self._use_psamailbackup = use_psamailbackup

	def copy_mail(self, global_context, migrator_server, subscription, issues):
		target_server = subscription.mail_target_server
		source_server = subscription.mail_source_server
		copy_content_mode = source_server.mail_settings.mode

		if target_server.ip() == source_server.ip():
			logger.info(
				"Mail server of subscription '%s' is migrated in assimilate mode, no need to copy mail content" % (
					subscription.name
				)
			)
			return
		
		if copy_content_mode == MailContent.NONE:
			logger.info(
				u"Mail content migration for subscription '%s' is disabled by user", subscription.name
			)
			return

		if target_server.is_windows() or source_server.is_windows():
			if copy_content_mode == MailContent.FULL:
				if (
					source_server.is_windows() 
					and 
					target_server.is_windows()
					and
					self._use_psamailbackup
				):
					copy_action = CopyMailPsaMailBackup(None, self._get_rsync)
				else:
					copy_action = CopyMailImapsync(imap_supported=True)
			elif copy_content_mode == MailContent.MESSAGES:
				copy_action = CopyMailImapsync(imap_supported=False)
		else:
			copy_action = PleskCopyMailContentRsync()

		copy_action.copy_mail(global_context, migrator_server, subscription, issues)

class PleskCopyMailContentRsync(CopyMailRsync):
	"""Copy mail messages with rsync from source Plesk to Plesk/PPA (Unix)"""

	def __init__(self):
		super(PleskCopyMailContentRsync, self).__init__(
			PleskSourceMailDirectory
		)

class PleskSourceMailDirectory(SourceMailDirectory):
	"""Provide paths to directories with mail on Plesk for Unix server"""

	def prepare(self):
		source_server = self.subscription.mail_source_server
		result = []

		for mailbox in self.domain.iter_mailboxes():
			source_mailbox_directory = self._get_source_mailbox_directory(source_server, mailbox)
			if source_mailbox_directory is not None:
				result.append(
					(source_mailbox_directory, TargetMailboxDirectory(mailbox.name.lower()))
				)

		return result

	def _get_source_mailbox_directory(self, source_server, mailbox):
		for mailbox_name in [mailbox.name, mailbox.name.lower()]:
			source_mailbox_directory = posixpath.join(
				source_server.mail_dir,
				self.domain.name.encode('idna'),
				mailbox_name
			)

			with source_server.runner() as runner:
				if runner.sh(
					'test -e {directory} && echo "yes" || echo "no"',
					dict(
						directory=source_mailbox_directory
					)
				).strip() == 'yes':
					return source_mailbox_directory

		return None
