from parallels.core import checking
from parallels.core.converter.business_objects.clients import ClientsConverter
from parallels.core.target_data_model import Model
from parallels.plesk.source.expand.converter.client import ExpandToPleskClientsConverter
from parallels.plesk.source.expand.converter.subscription import ExpandToPleskSubscriptionConverter
from parallels.plesk.converter.ip_mapping import IPMapper
from parallels.core.utils.common import group_by_id


class ExpandToPleskClientsAndSubscriptionsConverter(object):
	@staticmethod
	def convert(global_context, converted_resellers, expand_objects, report):
		"""Convert clients and subscriptions

		:type global_context: parallels.plesk.source.expand.global_context.ExpandGlobalMigrationContext
		:type converted_resellers: list[parallels.core.target_data_model.Reseller]
		:type expand_objects: parallels.plesk.source.expand.expand_data.model.Model
		:type report: parallels.core.checking.Report

		:rtype: parallels.core.target_data_model.Model
		"""
		resellers = group_by_id(converted_resellers, lambda r: r.login)
		target_model = Model(plans={}, resellers=resellers, clients={})
		clients_converter = ExpandToPleskClientsConverter()

		admin_fake_client = ClientsConverter.create_fake_client(None)
		target_model.clients[None] = admin_fake_client
		converted_clients = clients_converter.convert_clients(
			global_context.get_source_servers_info(),
			expand_objects,
			global_context.target_existing_objects.customers,
			global_context.migration_list_data.customers_mapping,
			report, global_context.password_holder
		)

		for reseller in target_model.resellers.values():
			reseller_fake_client = ClientsConverter.create_fake_client(reseller.login)
			reseller.clients.append(reseller_fake_client)

		ClientsConverter().assign_clients_to_resellers(
			target_model.clients, target_model.resellers.values(), converted_clients,
			global_context.migration_list_data.customers_mapping, report
		)

		ip_mapper = IPMapper(global_context.target_existing_objects)
		ip_mapper.set_ip_mapping(global_context.ip_mapping)
		subscriptions_converter = ExpandToPleskSubscriptionConverter(ip_mapper)
		plain_report = checking.PlainReport(report, *global_context.migrator._extract_source_objects_info())

		sources_info = global_context.get_source_servers_info()
		subscriptions_converter.convert(
			sources_info,
			global_context.target_existing_objects,
			global_context.migration_list_data.subscriptions_mapping,
			target_model, plain_report
		)

		return target_model
