from parallels.core.converter.adapter.reseller_plan_converter import ResellerPlanConverterAdapter
from parallels.core.utils import plesk_api_utils
from parallels.plesk.converter.reseller_plan import ResellerPlanConverter
from parallels.plesk.utils.xml_rpc.plesk.core import get_result_set_data, filter_object_not_found_error
from parallels.plesk.utils.xml_rpc.plesk.operator import ResellerPlanOperator


class PleskResellerPlanConverterAdapter(ResellerPlanConverterAdapter):
    def convert(self, global_context, resellers_migration_list, report):
        """Convert customers and subscriptions

        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :type resellers_migration_list: dict[str, str | None]
        :type report: parallels.core.reports.model.report.Report
        :rtype: list[parallels.core.target_data_model.ResellerPlan]
        """
        reseller_plan_names = list({n for n in resellers_migration_list.values() if n is not None})
        target_reseller_plans = self._fetch_target_reseller_plans(global_context, reseller_plan_names)

        if len(reseller_plan_names) == 0:
            return []

        target_plesk_api = global_context.conn.target.plesk_server.plesk_api()
        allowed_limits = plesk_api_utils.get_reseller_template_allowed_limits(target_plesk_api)
        allowed_permissions = plesk_api_utils.get_reseller_template_allowed_permissions(target_plesk_api)

        converted_reseller_plans = ResellerPlanConverter().convert_plans(
            global_context.get_primary_sources_info(),
            target_reseller_plans,
            reseller_plan_names,
            allowed_limits,
            allowed_permissions,
            report
        )
        return converted_reseller_plans

    @staticmethod
    def _fetch_target_reseller_plans(global_context, plan_names):
        """Fetch already existing admin's reseller plans from target panel

        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :type plan_names: list[str | unicode]
        :rtype: list[parallels.plesk.utils.xml_rpc.plesk.operator.reseller_plan.ResellerPlanInfo]
        """
        plesk_server = global_context.conn.target.plesk_server
        if plesk_server.is_power_user_mode or not plesk_server.can_manage_resellers:
            # Reseller plans are not supported in Power User mode
            return []

        if len(plan_names) == 0:
            return []

        plesk_api = global_context.conn.target.plesk_api()
        request = ResellerPlanOperator.Get(
            filter=ResellerPlanOperator.FilterByName(plan_names)
        )
        response = plesk_api.send(request)
        target_reseller_plans = get_result_set_data(filter_object_not_found_error(response))
        return target_reseller_plans
