from parallels.utils import cached
from parallels.common.utils.poa_utils import get_host_id_by_ip

from parallels.common.connections.target_servers import TargetServers
from parallels.target_panel_ppa.connections import target_server
from parallels.target_panel_ppa.connections.database_target_server import \
		PPADatabaseTargetServer
from parallels.common.hosting_check.entity_source.service import \
		TargetServiceInfo

class PPATargetPanel(object):
	@property
	def name(self):
		return 'PPA'

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

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

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

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

	def transfer_resource_limits_by_default(self):
		"""Whether resource limits should be transferred by default"""
		return False

	def get_subscription_nodes(self, conn, subscription_target_services, subscription_name):
		if subscription_target_services is not None:
			if subscription_target_services.web_ips is None or subscription_target_services.web_ips.v4 is None:
				web_node = None
			else:
				web_node_id = self._get_host_id_by_ip(subscription_target_services.web_ips.v4, conn)
				web_node = target_server.PPATargetServer(
					conn,
					web_node_id,
					subscription_target_services.web_ips.v4
				)

			if subscription_target_services.mail_ips is None or subscription_target_services.mail_ips.v4 is None:
				mail_node = None
			else:
				mail_node_id = self._get_host_id_by_ip(subscription_target_services.mail_ips.v4, conn)
				mail_node = target_server.PPATargetServer(
					conn,
					mail_node_id,
					subscription_target_services.mail_ips.v4
				)

			dns_nodes = []
			for dns_ip in subscription_target_services.dns_ips:
				dns_node_id = self._get_host_id_by_ip(dns_ip.v4, conn)
				dns_nodes.append(
					target_server.PPATargetServer(
						conn,
						dns_node_id,
						dns_ip.v4
					)
				)

			return TargetServers(
				web=web_node,
				mail=mail_node,
				database={
					db_server_type: PPADatabaseTargetServer(
						conn,
						db_server_params.host,
						db_server_params.port,
						db_server_params.admin,
						db_server_params.password,
					)
					for db_server_type, db_server_params in subscription_target_services.db_servers.iteritems()
				},
				dns=dns_nodes
			)
		else:
			return TargetServers(web=None, mail=None, database={}, dns=[])

	@cached
	def _get_host_id_by_ip(self, ip, conn):
		"""Determine POA host ID by IP address.
		As it is unlikely that this information changes during migration tool execution, 
		(no new nodes are registered, assimilated or removed by migration tool) 
		we can safely cache it."""
		return get_host_id_by_ip(conn.poa_api(), ip)

	def get_service_nodes(self, conn):
		service_nodes = []
		service_by_name = {
			'bind9' : 'dns',
			'ppa_mysql' : 'mysql',
			'ppa_pgsql' : 'postgresql',
			'ppa_mssql2012' : 'mssql',
			'ppa_apache' : 'web',
			'ppa_iis' : 'web',
			'ppa_postfix' : 'mail',
			'ppa_webmail' : 'mail',
			'ppa_smartermail' : 'mail'
		}

		for service_info in conn.poa_api().listServices():
			if service_info.service_name in service_by_name.keys():
				service_nodes.append(
					TargetServiceInfo(
						service_type=service_by_name[service_info.service_name],
						node=target_server.PPATargetServer(
							conn,
							service_info.host_id,
							conn.poa_api().getHost(service_info.host_id).ip_addresses[0].address
						)
					)
				)
		return service_nodes
