import posixpath
from parallels.core.content.mail.rsync import SourceMailDirectory
from parallels.core.utils.paths.mail_paths import MailboxDirectory
from parallels.core.content.mail.rsync import CopyMailRsync


class CpanelCopyMailRsync(CopyMailRsync):
    def _get_target_path(self, target_server, target_location, domain_name):
        return posixpath.join(
            target_server.mail_dir, domain_name,
            target_location.mailbox_name, 'Maildir'
        )


class CpanelSourceMailDirectory(SourceMailDirectory):
    """Provide paths to directories with mail on cPanel server.

    :type subscription: parallels.plesk.source.cpanel.migrated_subscription.CPanelMigratedSubscription
    """

    def __init__(self, subscription, domain):
        """
        :type subscription: parallels.plesk.source.cpanel.migrated_subscription.CPanelMigratedSubscription
        """
        self.subscription = subscription
        super(CpanelSourceMailDirectory, self).__init__(subscription, domain)

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

        for mailbox in self.domain.iter_mailboxes():
            source_directory = self._get_source_mailbox_directory(mailbox)

            if source_directory is None:
                continue

            if not mailbox.has_mailbox():
                # Skip mailnames with no mailbox (for example, forwardings)
                # which do not have any content on the source server
                with source_server.runner() as runner:
                    if not runner.file_exists(source_directory):
                        continue

            target_directory = MailboxDirectory(mailbox.name.lower())
            result.append((source_directory, target_directory))

        return result

    def get_excluded_files(self):
        """Exclude domain name directory, which is a root for user Maildirs."""
        return [self.domain.name]

    def _get_source_mailbox_directory(self, mailbox):
        """Return absolute path to mail directory.
        
        cPanel 11 domain has one default mail account with a Maildir +
        one Maildir per regular mail user. cPanel stores regular user maildirs
        inside default account's maildir.
        """
        sysuser_name = self.subscription.raw_dump.get_phosting_sysuser_name()
        home_dir = self.subscription.source_home_dir
        if mailbox.name == sysuser_name:
            # System (default) user mail directory
            return '{home_dir}/mail'.format(home_dir=home_dir)
        else:
            return '{home_dir}/mail/{domain}/{mailname}'.format(
                home_dir=home_dir,
                domain=mailbox.domain_name,
                mailname=mailbox.name,
            )
