from parallels.core import messages
from parallels.core.actions.base.subscription_backup_action import SubscriptionBackupAction
from parallels.core.actions.utils.logging_properties \
    import LoggingProperties
from parallels.core.dump.entity.password import Password
from parallels.core.reports.model.issue import Issue


class ChangeSmartermailPassword(SubscriptionBackupAction):
    """Fix passwords in backup when migrating to SmarterMail mail server"""

    def get_description(self):
        return messages.CHANGE_SMARTERMAIL_PASSWORDS_IN_BACKUPS

    def get_failure_message(self, global_context, subscription):
        """
        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :type subscription: parallels.core.migrated_subscription.MigratedSubscription
        """
        return messages.FAILED_CHANGE_SMARTERMAIL_PASSWORDS_FOR_SUBSCRIPTION % (subscription.name)

    def is_critical(self):
        """If action is critical or not

        If action is critical and it failed for a subscription, migration tool
        won't run the next operations for the subscription.

        :rtype: bool
        """
        return False

    def get_logging_properties(self):
        return LoggingProperties(info_log=False)

    def _run_subscription_backup(
        self, global_context, subscription, subscription_backup
    ):
        """
        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :type subscription: parallels.core.migrated_subscription.MigratedSubscription
        """
        if subscription.mail_target_server is None:
            return
        if not subscription.mail_target_server.is_windows():
            return

        for mailuser in subscription_backup.iter_mailboxes():
            if not self._password_is_smartermail_valid(mailuser.password.password_text) and mailuser.enabled:
                new_password = global_context.password_holder.get('mailuser', mailuser.full_name)
                mailuser.password = Password(password_text=new_password, password_type='plain')
                global_context.safe.add_issue_subscription(subscription.name, Issue(
                    'mailuser_invalid_password_for_windows_mail', Issue.SEVERITY_INFO,
                    messages.PASSWORD_MAIL_USER_S_DOES_NOT % mailuser.full_name,
                    messages.MAIL_USER_S_TRANSFERRED_ANOTHER_PASSWORD % (mailuser.full_name, new_password)
                ))

    @staticmethod
    def _password_is_smartermail_valid(password):
        """Validate password against SmarterMail requirements.
           Return True if password is valid, False otherwise."""
        return password is not None and len(password) >= 5
