from parallels.core.utils.common import unused
from parallels.core.utils.restore_hosting_utils import get_restore_hosting_utils


class TargetPanelBase(object):
	@property
	def name(self):
		raise NotImplementedError()

	def has_admin_reseller_plan_feature(self):
		"""Whethere admin reseller plans are supported for that target panel migration

		:rtype: bool
		"""
		raise NotImplementedError()

	def has_custom_subscriptions_feature(self):
		"""Whether subscriptions not assigned to plan are allowed

		:rtype: bool
		"""
		raise NotImplementedError()

	def has_admin_subscriptions_feature(self):
		"""Whether subscriptions assigned directly to admin are allowed

		:rtype: bool
		"""
		raise NotImplementedError()

	def get_default_admin_name(self):
		"""
		Return name of user to assign subscription, not assigned to particular user,
		if panel unable to assign subscription to administrator directly, None otherwise
		:rtype: str
		"""
		if self.has_admin_subscriptions_feature():
			return None
		raise NotImplementedError()

	def has_reseller_subscriptions_feature(self):
		"""Whether subscriptions assigned directly to reseller are allowed

		:rtype: bool
		"""
		raise NotImplementedError()

	def get_default_reseller_name(self, reseller):
		"""
		Return name of user to assign reseller subscription, not assigned to particular user,
		if panel unable to assign subscription to reseller directly, None otherwise
		:type reseller: parallels.core.dump.entity.reseller.Reseller
		:rtype: str
		"""
		unused(reseller)
		if self.has_reseller_subscriptions_feature():
			return None
		raise NotImplementedError()

	def has_dns_forwarding(self):
		"""Whether panel should support DNS forwarding migration feature

		:rtype: bool
		"""
		raise NotImplementedError()

	def is_test_dns_forwarding(self):
		"""Whether to test DNS forwarding feature on post-migration checks

		:rtype: bool
		"""
		return self.has_dns_forwarding()

	def is_subdomain_record_transferred_as_separate_zone(self):
		"""Whether subdomains's DNS record in parent domain's zone is transferred as new separate DNS zone

		By default is False, subdomains's DNS record is transferred as is, and still resides in parent domains's
		DNS zone. Still if subdomain on source had separate zone, it will have separate zone on target too.
		"""
		return False

	def is_transfer_resource_limits_by_default(self):
		"""Whether resource limits should be transferred by default

		:rtype: bool
		"""
		raise NotImplementedError()

	def is_write_failed_subscriptions_list(self):
		"""Whether to write failed subscriptions list file after migration

		:rtype: bool
		"""
		return True

	def is_encrypted_passwords_supported(self):
		"""Whether encrypted passwords (hashes) are supported when creating resellers and clients

		:rtype: bool
		"""
		return False

	def get_subscription_target_services(self, global_context, subscription_name):
		"""Get location of subscriptions's hosting services on target panel

		:type global_context: parallels.core.global_context.GlobalMigrationContext
		:type subscription_name: basestring
		:rtype: parallels.core.subscription_target_info.TargetServices
		"""
		raise NotImplementedError()

	def get_subscription_nodes(self, global_context, subscription_name):
		"""Get servers of subscription on target panel

		:type global_context: parallels.core.global_context.GlobalMigrationContext
		:type subscription_name: basestring
		:rtype: parallels.core.subscription_target_info.TargetServers
		"""
		raise NotImplementedError()

	def get_subscription_plesk_node(self, global_context, subscription_name):
		raise NotImplementedError()

	def use_source_plans(self):
		"""Return True if target panel supports migration of plans (service templates), False otherwise"""
		raise NotImplementedError()

	def get_service_nodes(self, conn):
		"""Return all service nodes of the panel

		Return list of service nodes to check services during service checks
		List consists of parallels.core.hosting_check.entity_source.service.TargetServiceInfo
		"""
		raise NotImplementedError()

	def get_connections(self, global_context):
		"""Get target panel connections"""
		raise NotImplementedError()

	def get_import_api(self, global_context):
		raise NotImplementedError()

	def get_converter_adapter(self):
		"""
		:rtype: parallels.core.client_subscription_converter.ClientSubscriptionConverterAdapter
		"""
		raise NotImplementedError()

	def get_hosting_check_messages_panel_id(self):
		raise NotImplementedError()

	def check_version(self, global_context):
		"""Check that target panel version is ok for migration purposes. Raise MigrationError othewise.

		Raised exception should contain information about supported versions for migration.
		By default, does nothing, override when adding new panel.

		:type global_context: parallels.core.global_context.GlobalMigrationContext
		:rtype: None
		"""
		pass

	@staticmethod
	def get_restore_hosting_utils(plesk_server):
		return get_restore_hosting_utils(plesk_server)

	def get_restore_hosting_additional_env_vars(self, global_context, subscription=None):
		"""Get additional target panel-specific environment variables to pass to hosting restoration utilities

		:type global_context: parallels.core.global_context.GlobalMigrationContext
		:type subscription: parallels.core.migrated_subscription.MigratedSubscription | None
		:rtype: dict[str, str]
		"""
		return dict()

	def get_import_dump_additional_env_vars(self, global_context):
		"""Get additional target panel-specific environment variables to pass to pmmcli when importing dump

		:type global_context: parallels.core.global_context.GlobalMigrationContext
		:rtype: dict[str, str]
		"""
		return dict()

	@property
	def sysuser_name_disallowed_chars(self):
		return {' '}