import posixpath

from parallels.core.logging import get_logger
from parallels.core import messages
from parallels.core.content.mail.mail_migrator import CopyMailMailMigrator
from parallels.core.content.mail.rsync import CopyMailRsync
from parallels.core.utils.paths.mail_paths import MailboxDirectory
from parallels.core.content.mail.rsync import SourceMailDirectory
from parallels.core.migrator_config import MailContent

logger = get_logger(__name__)


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

    def copy_mail(self, global_context, 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(messages.LOG_NO_NEED_TO_COPY_MAILCONTENT_BECAUSE_OF_ASSIMILATION, subscription.name)
            return
        
        if copy_content_mode == MailContent.NONE:
            logger.info(messages.LOG_NO_NEED_TO_COPY_MAILCONTENT_BECAUSE_DISABLED_BY_USER, subscription.name)
            return

        if target_server.is_windows() or source_server.is_windows():
            copy_action = CopyMailMailMigrator()
        else:
            copy_action = PleskCopyMailContentRsync()

        copy_action.copy_mail(global_context, subscription, issues)


class PleskCopyMailContentRsync(CopyMailRsync):
    """Copy mail messages with rsync"""

    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, MailboxDirectory(mailbox.name.lower()))
                )

        return result

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

                with source_server.runner() as runner:
                    if runner.file_exists(source_mailbox_directory):
                        return source_mailbox_directory

        return None
