import parallels.core.reports.plain_report
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.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.reports.model.report.Report

        :rtype: parallels.core.target_data_model.Model
        """
        resellers = group_by_id(converted_resellers, lambda r: r.login)
        target_model = Model(reseller_plans={}, 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
        )

        subscriptions_converter = ExpandToPleskSubscriptionConverter()
        plain_report = parallels.core.reports.plain_report.PlainReport(report, global_context.migration_list_data)

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

        return target_model
