from parallels.source.custom import messages
import logging
from parallels.core.actions.base.subscription_action import SubscriptionAction
from parallels.core.utils.database_utils import restore_db_from_dump_linux
from parallels.core.utils.unix_utils import get_safe_filename

logger = logging.getLogger(__name__)


class RestoreDBDumps(SubscriptionAction):
	def get_description(self):
		"""
		:rtype: basestring
		"""
		return messages.ACTION_RESTORE_DATABASES_FROM_DUMPS_DESCRIPTION

	def get_failure_message(self, global_context, subscription):
		"""
		:type global_context: parallels.common.global_context.GlobalMigrationContext
		:type subscription: parallels.common.migrated_subscription.MigratedSubscription
		:rtype: basestring
		"""
		return messages.ACTION_RESTORE_DATABASES_FROM_DUMPS_FAILURE

	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 filter_subscription(self, global_context, subscription):
		"""
		:type global_context: parallels.common.global_context.GlobalMigrationContext
		:type subscription: parallels.custom_panel_migrator.migrated_subscription.CustomPanelMigratedSubscription
		"""
		return subscription.light_backup is not None

	def run(self, global_context, subscription):
		"""
		:type global_context: parallels.custom_panel_migrator.global_context.CustomPanelGlobalMigrationContext
		:type subscription: parallels.custom_panel_migrator.migrated_subscription.CustomPanelMigratedSubscription
		"""
		databases_with_dumps = [db for db in subscription.light_backup.iter_databases() if db.dump is not None]
		for db in databases_with_dumps:
			logger.info("Restore database dump for {db_type} database '{db_name}' from '{dump}'".format(
				db_type=db.db_type, db_name=db.name, dump=db.dump
			))
			target_db_server = subscription.db_target_servers.get(db.db_type)
			if target_db_server is None:
				raise Exception(
					u"Database '{db_name}' of {db_type} will not be restored from dump as no {db_type} DB server is assigned to subscription".format(
						db_type=db.db_type, db_name=db.name,
					)
				)

			target_dump_filename = target_db_server.panel_server.get_session_file_path(
				'db_backup_%s_%s' % (subscription.name, db.name)
			)
			with target_db_server.runner() as runner:
				get_safe_filename(runner, target_dump_filename)
				runner.upload_file(db.dump, target_dump_filename)
				restore_db_from_dump_linux(target_db_server, db.name, target_dump_filename)
				runner.remove_file(target_dump_filename)
