from parallels.core.logging import get_logger
from parallels.core.utils.common import is_empty_iterator, safe_format
from parallels.plesk import messages
from parallels.core.actions.base.subscription_action import SubscriptionAction

logger = get_logger(__name__)


class DeployMailAccounts(SubscriptionAction):
    def get_description(self):
        return messages.ACTION_DEPLOY_MAIL_ACCOUNTS

    def get_failure_message(self, global_context, subscription):
        return messages.ACTION_DEPLOY_MAIL_ACCOUNTS_FAILED.format(subscription_name=subscription.name)

    def is_critical(self):
        return False

    def filter_subscription(self, global_context, subscription):
        return not is_empty_iterator(subscription.converted_dump.iter_all_mail_accounts())

    def run(self, global_context, subscription):
        """Perform creation of mail accounts for given subscription on target Plesk

        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :type subscription: parallels.core.migrated_subscription.MigratedSubscription
        """
        for mail_account_dump in subscription.converted_dump.iter_all_mail_accounts():
            if global_context.hosting_repository.mail_account.is_exists_by_subscription(
                subscription.name,
                mail_account_dump.mail_user_name,
                mail_account_dump.domain_name
            ):
                logger.info(messages.ACTION_DEPLOY_MAIL_ACCOUNTS_CREATE_MAIL_ACCOUNT_EXISTS.format(
                    mail_account_name=mail_account_dump.name
                ))
                continue

            logger.info(messages.ACTION_DEPLOY_MAIL_ACCOUNTS_CREATE_MAIL_ACCOUNT.format(
                mail_account_name=mail_account_dump.name,
                subscription_name=subscription.name
            ))

            try:
                global_context.hosting_repository.mail_account.create_from_dump(subscription.name, mail_account_dump)
            except Exception as e:
                logger.exception()
                # place error into report and proceed to next mail account
                global_context.safe.fail_subscription(
                    subscription.name,
                    safe_format(
                        messages.ACTION_DEPLOY_MAIL_ACCOUNTS_CREATE_MAIL_ACCOUNT_ERROR,
                        mail_account_name=mail_account_dump.name,
                        subscription_name=subscription.name,
                        reason=e
                    ),
                    is_critical=False
                )
                continue

            if mail_account_dump.is_enable_forwarding:
                # set forwarding for just created mail account
                logger.info(messages.ACTION_DEPLOY_MAIL_ACCOUNTS_SET_FORWARDING.format(
                    mail_account_name=mail_account_dump.name,
                    subscription_name=subscription.name
                ))
                if len(mail_account_dump.forwarding_addresses) == 0:
                    global_context.safe.fail_subscription(
                        subscription.name,
                        messages.ACTION_DEPLOY_MAIL_ACCOUNTS_SET_FORWARDING_ERROR_NO_ADDRESSES.format(
                            mail_account_name=mail_account_dump.name,
                            subscription_name=subscription.name
                        ),
                        is_critical=False
                    )
                    continue
                try:
                    global_context.hosting_repository.mail_account.set_forwarding(
                        subscription.name,
                        mail_account_dump.name,
                        mail_account_dump.is_enable_forwarding,
                        mail_account_dump.forwarding_addresses
                    )
                except Exception as e:
                    logger.exception()
                    # place error into report and proceed to next mail account
                    global_context.safe.fail_subscription(
                        subscription.name,
                        safe_format(
                            messages.ACTION_DEPLOY_MAIL_ACCOUNTS_SET_FORWARDING_ERROR,
                            mail_account_name=mail_account_dump.name,
                            subscription_name=subscription.name,
                            reason=e
                        ),
                        is_critical=False
                    )
                    continue

            if len(mail_account_dump.aliases) > 0:
                # set aliases for just created mail account
                logger.info(messages.ACTION_DEPLOY_MAIL_ACCOUNTS_SET_ALIASES.format(
                    mail_account_name=mail_account_dump.name,
                    subscription_name=subscription.name
                ))
                try:
                    global_context.hosting_repository.mail_account.set_aliases(
                        subscription.name,
                        mail_account_dump.name,
                        mail_account_dump.aliases
                    )
                except Exception as e:
                    logger.exception()
                    # place error into report and proceed to next mail account
                    global_context.safe.fail_subscription(
                        subscription.name,
                        safe_format(
                            messages.ACTION_DEPLOY_MAIL_ACCOUNTS_SET_FORWARDING_ERROR,
                            mail_account_name=mail_account_dump.name,
                            subscription_name=subscription.name,
                            reason=e
                        ),
                        is_critical=False
                    )
                    continue
