from parallels.common.import_api.import_api import ImportAPI
from parallels.common.utils import plesk_utils
from parallels.target_panel_plesk.import_api.import_api_unix import PleskUnixImportAPI
from parallels.target_panel_plesk.import_api.import_api_windows import PleskWindowsImportAPI
from parallels.target_panel_ppa.import_api.import_api import PPAImportAPI
from parallels.target_panel_ppa.import_api.model import PPAServiceTemplateInfo
from parallels.target_panel_pvps.models.existing_objects_model import PVPSServiceTemplate, PVPSResource
from parallels.utils import find_first


class PVPSImportAPI(ImportAPI):
	system_name = 'PVPS'

	def __init__(self, conn, webspaces_requests_holder):
		self._conn = conn
		self._poa = conn.poa_api()
		self._ppa_import_api = PPAImportAPI(conn, webspaces_requests_holder)

	def has_addon_service_templates(self):
		return False

	def create_reseller(self, reseller):
		return self._ppa_import_api.create_reseller(reseller)

	def create_customer(self, owner_id, customer):
		return self._ppa_import_api.create_customer(owner_id, customer)

	def list_resellers(self, reseller_logins):
		return self._ppa_import_api.list_resellers(reseller_logins)

	def list_customers(self, customer_logins):
		return self._ppa_import_api.list_customers(customer_logins)

	def get_request_status(self, request_id):
		return self._ppa_import_api.get_request_status(request_id)

	def list_webspaces_brief(self, domain_names):
		# No needed for PVPS
		return []

	def get_domain_dns_server_ips(self, target_server, domain_name):
		"""
		:type target_server: parallels.common.connections.target_servers.TargetServer
		"""
		return [target_server.ip()]

	def refresh_node_components(self, node):
		plesk_utils.refresh_node_components(node)

	def get_service_template_info_list(self, service_template_ids):
		service_templates = []
		for st_id in set(service_template_ids):
			st_details = self._poa.getServiceTemplate(st_id, get_resources=True)

			pvps_resources = []
			for r in st_details.resource_types:
				pvps_resources.append(
					PVPSResource(rt_id=r.rt_id, name=r.name, resclass_name=r.resclass_name, limit=r.limit,
						act_params={x.name: x.value for x in r.act_params}
					))

			service_templates.append(
				PVPSServiceTemplate(
					id=st_details.st_id, name=st_details.name, owner_id=st_details.owner_id,
					resource_types=pvps_resources
				)
			)
		return service_templates

	def get_service_template_list(self, owner_id, service_template_names=None):
		service_templates_brief = []
		for st in self._poa.getServiceTemplateList(owner_id, active=True):
			if service_template_names is None or st.name in service_template_names:
				if self._is_pvps_service_template(st.st_id):
					service_templates_brief.append(PPAServiceTemplateInfo(
						st_id=st.st_id, name=st.name, owner_id=st.owner_id
					))
		return service_templates_brief

	def get_addon_service_template_list(self, owner_id, active=None):
		# There are no addon templates in PPA/PVPS, return empty list
		return []

	@staticmethod
	def get_dedicated_app_pool_user(subscription):
		"""
		:type subscription: parallels.common.migrated_subscription.MigratedSubscription
		"""
		return PVPSImportAPI._get_plesk_import_api(subscription).get_dedicated_app_pool_user(subscription)

	@staticmethod
	def repair_webspace_security(subscription):
		"""
		:type subscription: parallels.common.migrated_subscription.MigratedSubscription
		"""
		return PVPSImportAPI._get_plesk_import_api(subscription).repair_webspace_security(subscription)

	def update_webspace_subdomains_security_metadata_location(self, subscription):
		"""
		:type subscription: parallels.common.migrated_subscription.MigratedSubscription
		:rtype: None
		"""
		return PVPSImportAPI._get_plesk_import_api(subscription).repair_webspace_security(subscription)

	def _is_pvps_service_template(self, service_template_id):
		"""Check if provided service template is Plesk in VPS service template"""
		pvps_resources = {'PVPS_Cloud', 'PVPS_Panel', 'PVPS_License'}

		st_info = self._poa.getServiceTemplate(st_id=service_template_id, get_resources=True)
		st_resource_names = {resource.name for resource in st_info.resource_types}
		return (
			st_resource_names > pvps_resources and
			find_first(st_resource_names, lambda x: x.startswith('PVPS_Config_')) is not None
		)

	@staticmethod
	def _get_plesk_import_api(subscription):
		"""
		:type subscription: parallels.common.migrated_subscription.MigratedSubscription
		"""
		return PleskWindowsImportAPI if subscription.panel_target_server.is_windows() else PleskUnixImportAPI
