from parallels.core import safe_format
from parallels.core.utils.common import cached, default
from parallels.plesk.source.mail import messages


class MigratedMailAddressPair(object):
    """
    :type _global_context: parallels.plesk.source.mail.global_context.MailGlobalMigrationContext
    :type _migration_list_mail_address_pair: parallels.plesk.source.mail.mail_migration_list.MigrationListMailAddressPair
    """

    def __init__(self, global_context, migration_list_mail_address_pair):
        """
        :type global_context: parallels.plesk.source.mail.global_context.MailGlobalMigrationContext
        :type migration_list_mail_address_pair: parallels.plesk.source.mail.mail_migration_list.MigrationListMailAddressPair
        """
        self._global_context = global_context
        self._migration_list_mail_address_pair = migration_list_mail_address_pair
        self._target_password = None

    def description(self):
        """Get short description of the mail address pair, which could be used for logging and error messages

        :rtype: str | unicode
        """
        return safe_format(
            messages.MAIL_ADDRESS_PAIR_OBJECT_DESCRIPTION,
            source_email=self.source_email,
            target_email=self.target_email
        )

    @property
    def source_email(self):
        """
        :rtype: str | unicode
        """
        return self._migration_list_mail_address_pair.source_email

    @property
    def source_password(self):
        """
        :rtype: str | unicode | None
        """
        return default(
            self._migration_list_mail_address_pair.source_password,
            self._persistent_settings.source_password
        )

    @property
    def target_mailname(self):
        """
        :rtype: str | unicode
        """
        return self._migration_list_mail_address_pair.target_mailname

    @property
    def target_domain(self):
        """
        :rtype: str | unicode
        """
        return self._global_context.conn.get_target_domain_name()

    @property
    def target_subscription_name(self):
        """
        :rtype: str | unicode
        """
        return self._global_context.target_subscription_name

    @property
    def target_email(self):
        """
        :rtype: str | unicode
        """
        return '%s@%s' % (
            self._migration_list_mail_address_pair.target_mailname,
            self._global_context.conn.get_target_domain_name()
        )

    @property
    def new_target_password(self):
        """Password which should be used to create new mailbox if it does not exist on the target server

        :rtype: str | unicode | None
        """
        return default(
            self._migration_list_mail_address_pair.target_password,
            self._persistent_settings.target_password
        )

    @property
    def target_password(self):
        """Password of the target mailbox

        :rtype: str | unicode | None
        """
        return self._target_password

    @target_password.setter
    def target_password(self, password):
        """
        :type password: str | unicode
        :rtype: None
        """
        self._target_password = password

    @property
    def imap_host(self):
        """
        :rtype: str | unicode
        """
        return default(
            self._migration_list_mail_address_pair.imap_host,
            self._persistent_settings.imap_host
        )

    @property
    def imap_port(self):
        """
        :rtype: int | None
        """
        return default(
            self._migration_list_mail_address_pair.imap_port,
            self._persistent_settings.imap_port
        )

    @property
    def ignore_security_warnings(self):
        """
        :rtype: bool | None
        """
        return default(
            self._migration_list_mail_address_pair.ignore_security_warnings,
            self._persistent_settings.ignore_security_warnings
        )

    @property
    def imap_encryption(self):
        """
        :rtype: int | None
        """
        return default(
            self._migration_list_mail_address_pair.imap_encryption,
            self._persistent_settings.imap_encryption
        )

    @property
    def imap_timeout(self):
        """
        :rtype: int | None
        """
        return default(
            self._migration_list_mail_address_pair.imap_timeout,
            self._persistent_settings.imap_timeout
        )

    @property
    def imap_folder_separator(self):
        """
        :rtype: int | None
        """
        return default(
            self._migration_list_mail_address_pair.imap_folder_separator,
            self._persistent_settings.imap_folder_separator
        )

    @property
    @cached
    def _persistent_settings(self):
        """Get persistent mail settings of this mail address pair.

        Persistent settings are stored on filesystem and include various parameters, like IMAP port, IMAP host,
        IMAP directory separator, and so on. They are required to avoid asking customer for
        the settings each time, e.g. when he/she wants to re-sync mailbox. When customer starts initial import,
        he/she asked to provide the settings, and then the settings are saved to a file. When customer clicks
        on "re-sync" button, migrator reads the settings from a file.

        :rtype: parallels.plesk.source.mail.settings_storage.MailAddressPairSettings | None
        """
        return self._global_context.settings_storage.get_settings(self.source_email, self.target_mailname)
