from parallels.core import safe_format
from parallels.core.hosting_repository.database_user import CreateDatabaseUserEntity
from parallels.core.utils.database_server_type import DatabaseServerType
from parallels.plesk.source.web import messages
from parallels.plesk.source.web.actions.base.database_user import DatabaseUserAction
from parallels.plesk.source.web.actions.deploy.database import DeployDatabases


class DeployDatabaseUsers(DatabaseUserAction):
    def get_description(self):
        """Get short description of action as string

        :rtype: str | unicode
        """
        return messages.ACTION_DEPLOY_DATABASE_USERS_DESCRIPTION

    def get_failure_message(self, global_context):
        """Get message for situation when action failed

        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :rtype: str | unicode
        """
        return messages.ACTION_DEPLOY_DATABASE_USERS_FAILURE

    def get_failure_message_for_database_user(self, global_context, database, database_user):
        """Get message for situation when action failed for specific database user

        :type global_context: parallels.plesk.source.web.global_context.WebGlobalMigrationContext
        :type database: parallels.plesk.source.web.migrated_database.WebMigratedDatabase
        :type database_user: parallels.plesk.source.web.migrated_database_user.WebMigratedDatabaseUser
        :rtype: str | unicode | None
        """
        return safe_format(
            messages.ACTION_DEPLOY_DATABASE_USERS_FAILURE_FOR_USER,
            user=database_user.target_username,
            database=database.target_name
        )

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

        If action is critical and it failed, migration tool completely stops.
        Otherwise it proceeds to the next steps of migrations.

        :rtype: bool
        """
        return False

    def get_pre_requirement_actions(self):
        """Get list of pre-requirements to execute that action: list of action classes.

        If any of these pre-requirements were not executed or execution failed, then this action won't be executed.

        :rtype: list[object]
        """
        return [DeployDatabases]

    def run_for_database_user(self, global_context, database_user):
        """Run action for single migrated database user

        :type global_context: parallels.plesk.source.web.global_context.WebGlobalMigrationContext
        :type database_user: parallels.plesk.source.web.migrated_database_user.WebMigratedDatabaseUser
        :rtype: list[parallels.core.reports.model.issue.Issue] | None
        """
        if global_context.hosting_repository.database_user.is_exists_by_subscription(
            database_user.target_subscription_name, database_user.target_username
        ):
            return

        global_context.hosting_repository.database_user.create(
            CreateDatabaseUserEntity(
                database_user.target_username,
                database_user.source_password,
                CreateDatabaseUserEntity.PASSWORD_TYPE_PLAIN,
                database_user.database.target_name,
                DatabaseServerType.MYSQL,
                database_user.database.target_server.host(),
                database_user.database.target_server.port()
            ),
            database_user.target_subscription_name,
        )
