from ._base_response import EC2BaseResponse


class Fleets(EC2BaseResponse):
    def delete_fleets(self) -> str:
        fleet_ids = self._get_multi_param("FleetId.")
        terminate_instances = self._get_bool_param("TerminateInstances")
        fleets = self.ec2_backend.delete_fleets(fleet_ids, terminate_instances)
        template = self.response_template(DELETE_FLEETS_TEMPLATE)
        return template.render(fleets=fleets)

    def describe_fleet_instances(self) -> str:
        fleet_id = self._get_param("FleetId")

        instances = self.ec2_backend.describe_fleet_instances(fleet_id)
        template = self.response_template(DESCRIBE_FLEET_INSTANCES_TEMPLATE)
        return template.render(fleet_id=fleet_id, instances=instances)

    def describe_fleets(self) -> str:
        fleet_ids = self._get_multi_param("FleetId.")

        requests = self.ec2_backend.describe_fleets(fleet_ids)
        template = self.response_template(DESCRIBE_FLEETS_TEMPLATE)
        rend = template.render(requests=requests)
        return rend

    def create_fleet(self) -> str:
        on_demand_options = self._get_multi_param_dict("OnDemandOptions")
        spot_options = self._get_multi_param_dict("SpotOptions")
        target_capacity_specification = self._get_multi_param_dict(
            "TargetCapacitySpecification"
        )
        launch_template_configs = self._get_multi_param(
            param_prefix="LaunchTemplateConfigs"
        )
        # Our multi_param function doesn't understand when to return a list, a string, or a dictionary
        # So we'll have to help it a little, by explicitly asking for a dict if we're getting anything else back
        for idx, config in enumerate(launch_template_configs, start=1):
            if (overrides := config.get("Overrides")) and not isinstance(
                overrides, dict
            ):
                config["Overrides"] = self._get_multi_param(
                    f"LaunchTemplateConfigs.{idx}.Overrides",
                    skip_result_conversion=True,
                )
            if (spec := config.get("LaunchTemplateSpecification")) and not isinstance(
                spec, dict
            ):
                config["LaunchTemplateSpecification"] = self._get_multi_param_dict(
                    f"LaunchTemplateConfigs.{idx}.LaunchTemplateSpecification"
                )

        excess_capacity_termination_policy = self._get_param(
            "ExcessCapacityTerminationPolicy"
        )
        replace_unhealthy_instances = self._get_param("ReplaceUnhealthyInstances")
        terminate_instances_with_expiration = self._get_param(
            "TerminateInstancesWithExpiration", if_none=True
        )
        fleet_type = self._get_param("Type", if_none="maintain")
        valid_from = self._get_param("ValidFrom")
        valid_until = self._get_param("ValidUntil")

        tag_specifications = self._get_multi_param("TagSpecification")

        request = self.ec2_backend.create_fleet(
            on_demand_options=on_demand_options,
            spot_options=spot_options,
            target_capacity_specification=target_capacity_specification,
            launch_template_configs=launch_template_configs,
            excess_capacity_termination_policy=excess_capacity_termination_policy,
            replace_unhealthy_instances=replace_unhealthy_instances,
            terminate_instances_with_expiration=terminate_instances_with_expiration,
            fleet_type=fleet_type,
            valid_from=valid_from,
            valid_until=valid_until,
            tag_specifications=tag_specifications,
        )

        template = self.response_template(CREATE_FLEET_TEMPLATE)
        return template.render(request=request)


CREATE_FLEET_TEMPLATE = """<CreateFleetResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
    <requestId>60262cc5-2bd4-4c8d-98ed-example</requestId>
    <fleetId>{{ request.id }}</fleetId>
    {% if request.fleet_type == "instant" %}
    <fleetInstanceSet>
        {% for instance in request.on_demand_instances %}
        <item>
            <instanceType>{{ instance["instance"].instance_type }}</instanceType>
            <lifecycle>on-demand</lifecycle>
            <instanceIds>
                <item>{{ instance["instance"].id }}</item>
            </instanceIds>
        </item>
        {% endfor %}
        {% for instance in request.spot_requests %}
        <item>
            <instanceType>{{ instance.instance.instance_type }}</instanceType>
            <lifecycle>spot</lifecycle>
            <instanceIds>
                <item>{{ instance.instance.id }}</item>
            </instanceIds>
        </item>
        {% endfor %}
    </fleetInstanceSet>
    {% endif %}
</CreateFleetResponse>"""

DESCRIBE_FLEETS_TEMPLATE = """<DescribeFleetsResponse xmlns="http://ec2.amazonaws.com/doc/2016-09-15/">
    <requestId>4d68a6cc-8f2e-4be1-b425-example</requestId>
    <fleetSet>
        {% for request in requests %}
        <item>
            <fleetId>{{ request.id }}</fleetId>
            <fleetState>{{ request.state }}</fleetState>
            <excessCapacityTerminationPolicy>{{ request.excess_capacity_termination_policy }}</excessCapacityTerminationPolicy>
            <fulfilledCapacity>{{ request.fulfilled_capacity }}</fulfilledCapacity>
            <fulfilledOnDemandCapacity>{{ request.fulfilled_on_demand_capacity }}</fulfilledOnDemandCapacity>
            <launchTemplateConfigs>
                {% for config in request.launch_template_configs %}
                <item>
                    <launchTemplateSpecification>
                        <launchTemplateId>{{ config.LaunchTemplateSpecification.LaunchTemplateId }}</launchTemplateId>
                        <version>{{ config.LaunchTemplateSpecification.Version }}</version>
                    </launchTemplateSpecification>
                    {% if config.Overrides %}
                    <overrides>
                        {% for override in config.Overrides %}
                        <item>
                            {% if override.AvailabilityZone %}
                            <availabilityZone>{{ override.AvailabilityZone }}</availabilityZone>
                            {% endif %}
                            {% if override.InstanceType %}
                            <instanceType>{{ override.InstanceType }}</instanceType>
                            {% endif %}
                            {% if override.InstanceRequirements %}
                            <instanceRequirements>
                                {% if override.InstanceRequirements.AcceleratorCount %}
                                <acceleratorCount>
                                    {% if override.InstanceRequirements.AcceleratorCount.Max %}
                                    <max>{{ override.InstanceRequirements.AcceleratorCount.Max }}</max>
                                    {% endif %}
                                    {% if override.InstanceRequirements.AcceleratorCount.Min %}
                                    <min>{{ override.InstanceRequirements.AcceleratorCount.Min }}</min>
                                    {% endif %}
                                </acceleratorCount>
                                {% endif %}
                                {% if override.InstanceRequirements.AcceleratorManufacturer %}
                                <acceleratorManufacturerSet>
                                    {% for manufacturer in override.InstanceRequirements.AcceleratorManufacturer %}
                                    <item>{{ manufacturer }}</item>
                                    {% endfor %}
                                </acceleratorManufacturerSet>
                                {% endif %}
                                {% if override.InstanceRequirements.AcceleratorName %}
                                <acceleratorNameSet>
                                    {% for name in override.InstanceRequirements.AcceleratorName %}
                                    <item>{{ name }}</item>
                                    {% endfor %}
                                </acceleratorNameSet>
                                {% endif %}
                                {% if override.InstanceRequirements.AcceleratorTotalMemoryMiB %}
                                <acceleratorTotalMemoryMiB>
                                    {% if override.InstanceRequirements.AcceleratorTotalMemoryMiB.Max %}
                                    <max>{{ override.InstanceRequirements.AcceleratorTotalMemoryMiB.Max }}</max>
                                    {% endif %}
                                    {% if override.InstanceRequirements.AcceleratorTotalMemoryMiB.Min %}
                                    <min>{{ override.InstanceRequirements.AcceleratorTotalMemoryMiB.Min }}</min>
                                    {% endif %}
                                </acceleratorTotalMemoryMiB>
                                {% endif %}
                                {% if override.InstanceRequirements.AcceleratorType %}
                                <acceleratorTypeSet>
                                    {% for type in override.InstanceRequirements.AcceleratorType %}
                                    <item>{{ type }}</item>
                                    {% endfor %}
                                </acceleratorTypeSet>
                                {% endif %}
                                {% if override.InstanceRequirements.BareMetal %}
                                <bareMetal>{{ override.InstanceRequirements.BareMetal }}</bareMetal>
                                {% endif %}
                                {% if override.InstanceRequirements.BaselineEbsBandwidthMbps %}
                                <baselineEbsBandwidthMbps>
                                    {% if override.InstanceRequirements.BaselineEbsBandwidthMbps.Min %}
                                    <min>{{ override.InstanceRequirements.BaselineEbsBandwidthMbps.Min }}</min>
                                    {% endif %}
                                    {% if override.InstanceRequirements.BaselineEbsBandwidthMbps.Max %}
                                    <max>{{ override.InstanceRequirements.BaselineEbsBandwidthMbps.Max }}</max>
                                    {% endif %}
                                </baselineEbsBandwidthMbps>
                                {% endif %}
                                {% if override.InstanceRequirements.BurstablePerformance %}
                                <burstablePerformance>{{ override.InstanceRequirements.BurstablePerformance }}</burstablePerformance>
                                {% endif %}
                                {% if override.InstanceRequirements.CpuManufacturer %}
                                <cpuManufacturerSet>
                                    {% for manufacturer in override.InstanceRequirements.CpuManufacturer %}
                                    <item>{{ manufacturer }}</item>
                                    {% endfor %}
                                </cpuManufacturerSet>
                                {% endif %}
                                {% if override.InstanceRequirements.ExcludedInstanceType %}
                                <excludedInstanceTypeSet>
                                    {% for type in override.InstanceRequirements.ExcludedInstanceType %}
                                    <item>{{ type }}</item>
                                    {% endfor %}
                                </excludedInstanceTypeSet>
                                {% endif %}
                                {% if override.InstanceRequirements.InstanceGeneration %}
                                <instanceGenerationSet>
                                    {% for generation in override.InstanceRequirements.InstanceGeneration %}
                                    <item>{{ generation }}</item>
                                    {% endfor %}
                                </instanceGenerationSet>
                                {% endif %}
                                {% if override.InstanceRequirements.LocalStorage %}
                                <localStorage>{{ override.InstanceRequirements.LocalStorage }}</localStorage>
                                {% endif %}
                                {% if override.InstanceRequirements.LocalStorageType %}
                                <localStorageTypeSet>
                                    {% for type in override.InstanceRequirements.LocalStorageType %}
                                    <item>{{ type }}</item>
                                    {% endfor %}
                                </localStorageTypeSet>
                                {% endif %}
                                {% if override.InstanceRequirements.MemoryGiBPerVCpu %}
                                <memoryGiBPerVCpu>
                                    {% if override.InstanceRequirements.MemoryGiBPerVCpu.Min %}
                                    <min>{{ override.InstanceRequirements.MemoryGiBPerVCpu.Min }}</min>
                                    {% endif %}
                                    {% if override.InstanceRequirements.MemoryGiBPerVCpu.Max %}
                                    <max>{{ override.InstanceRequirements.MemoryGiBPerVCpu.Max }}</max>
                                    {% endif %}
                                </memoryGiBPerVCpu>
                                {% endif %}
                                {% if override.InstanceRequirements.MemoryMiB %}
                                <memoryMiB>
                                    {% if override.InstanceRequirements.MemoryMiB.Min %}
                                    <min>{{ override.InstanceRequirements.MemoryMiB.Min }}</min>
                                    {% endif %}
                                    {% if override.InstanceRequirements.MemoryMiB.Max %}
                                    <max>{{ override.InstanceRequirements.MemoryMiB.Max }}</max>
                                    {% endif %}
                                </memoryMiB>
                                {% endif %}
                                {% if override.InstanceRequirements.NetworkInterfaceCount %}
                                <networkInterfaceCount>
                                    {% if override.InstanceRequirements.NetworkInterfaceCount.Max %}
                                    <max>{{ override.InstanceRequirements.NetworkInterfaceCount.Max }}</max>
                                    {% endif %}
                                    {% if override.InstanceRequirements.NetworkInterfaceCount.Min %}
                                    <min>{{ override.InstanceRequirements.NetworkInterfaceCount.Min }}</min>
                                    {% endif %}
                                </networkInterfaceCount>
                                {% endif %}
                                {% if override.InstanceRequirements.OnDemandMaxPricePercentageOverLowestPrice %}
                                <onDemandMaxPricePercentageOverLowestPrice>{{ override.InstanceRequirements.OnDemandMaxPricePercentageOverLowestPrice }}</onDemandMaxPricePercentageOverLowestPrice>
                                {% endif %}
                                {% if override.InstanceRequirements.RequireHibernateSupport %}
                                <requireHibernateSupport>{{ override.InstanceRequirements.RequireHibernateSupport }}</requireHibernateSupport>
                                {% endif %}
                                {% if override.InstanceRequirements.SpotMaxPricePercentageOverLowestPrice %}
                                <spotMaxPricePercentageOverLowestPrice>{{ override.InstanceRequirements.SpotMaxPricePercentageOverLowestPrice }}</spotMaxPricePercentageOverLowestPrice>
                                {% endif %}
                                {% if override.InstanceRequirements.TotalLocalStorageGB %}
                                <totalLocalStorageGB>
                                    {% if override.InstanceRequirements.TotalLocalStorageGB.Min %}
                                    <min>{{ override.InstanceRequirements.TotalLocalStorageGB.Min }}</min>
                                    {% endif %}
                                    {% if override.InstanceRequirements.TotalLocalStorageGB.Max %}
                                    <max>{{ override.InstanceRequirements.TotalLocalStorageGB.Max }}</max>
                                    {% endif %}
                                </totalLocalStorageGB>
                                {% endif %}
                                {% if override.InstanceRequirements.VCpuCount %}
                                <vCpuCount>
                                    {% if override.InstanceRequirements.VCpuCount.Min %}
                                    <min>{{ override.InstanceRequirements.VCpuCount.Min }}</min>
                                    {% endif %}
                                    {% if override.InstanceRequirements.VCpuCount.Max %}
                                    <max>{{ override.InstanceRequirements.VCpuCount.Max }}</max>
                                    {% endif %}
                                </vCpuCount>
                                {% endif %}
                            </instanceRequirements>
                            {% endif %}
                            {% if override.MaxPrice %}
                            <maxPrice>{{ override.MaxPrice }}</maxPrice>
                            {% endif %}
                            {% if override.Placement %}
                            <placement>
                                {% if override.Placement.GroupName %}
                                <groupName>{{ override.Placement.GroupName }}</groupName>
                                {% endif %}
                            </placement>
                            {% endif %}
                            {% if override.Priority %}
                            <priority>{{ override.Priority }}</priority>
                            {% endif %}
                            {% if override.SubnetId %}
                            <subnetId>{{ override.SubnetId }}</subnetId>
                            {% endif %}
                            {% if override.WeightedCapacity %}
                            <weightedCapacity>{{ override.WeightedCapacity }}</weightedCapacity>
                            {% endif %}
                        </item>
                        {% endfor %}
                    </overrides>
                    {% endif %}
                </item>
                {% endfor %}
            </launchTemplateConfigs>
            <targetCapacitySpecification>
                <totalTargetCapacity>{{ request.target_capacity }}</totalTargetCapacity>
                {% if request.on_demand_target_capacity %}
                <onDemandTargetCapacity>{{ request.on_demand_target_capacity }}</onDemandTargetCapacity>
                {% endif %}
                {% if request.spot_target_capacity %}
                <spotTargetCapacity>{{ request.spot_target_capacity }}</spotTargetCapacity>
                {% endif %}
                <defaultTargetCapacityType>{{ request.target_capacity_specification.DefaultTargetCapacityType }}</defaultTargetCapacityType>
            </targetCapacitySpecification>
            {% if request.spot_options %}
            <spotOptions>
                {% if request.spot_options.AllocationStrategy %}
                <allocationStrategy>{{ request.spot_options.AllocationStrategy }}</allocationStrategy>
                {% endif %}
                {% if request.spot_options.InstanceInterruptionBehavior %}
                <instanceInterruptionBehavior>{{ request.spot_options.InstanceInterruptionBehavior }}</instanceInterruptionBehavior>
                {% endif %}
                {% if request.spot_options.InstancePoolsToUseCount %}
                <instancePoolsToUseCount>{{ request.spot_options.InstancePoolsToUseCount }}</instancePoolsToUseCount>
                {% endif %}
                {% if request.spot_options.MaintenanceStrategies %}
                <maintenanceStrategies>
                    {% if request.spot_options.MaintenanceStrategies.CapacityRebalance %}
                    <capacityRebalance>
                        {% if request.spot_options.MaintenanceStrategies.CapacityRebalance.ReplacementStrategy %}
                        <replacementStrategy>{{ request.spot_options.MaintenanceStrategies.CapacityRebalance.ReplacementStrategy }}</replacementStrategy>
                        {% endif %}
                        {% if request.spot_options.MaintenanceStrategies.CapacityRebalance.TerminationDelay %}
                        <terminationDelay>{{ request.spot_options.MaintenanceStrategies.CapacityRebalance.TerminationDelay }}</terminationDelay>
                        {% endif %}
                    </capacityRebalance>
                    {% endif %}
                </maintenanceStrategies>
                {% endif %}
                {% if request.spot_options.MaxTotalPrice %}
                <maxTotalPrice>{{ request.spot_options.MaxTotalPrice }}</maxTotalPrice>
                {% endif %}
                {% if request.spot_options.MinTargetCapacity %}
                <minTargetCapacity>{{ request.spot_options.MinTargetCapacity }}</minTargetCapacity>
                {% endif %}
                {% if request.spot_options.SingleAvailabilityZone %}
                <singleAvailabilityZone>{{ request.spot_options.SingleAvailabilityZone }}</singleAvailabilityZone>
                {% endif %}
                {% if request.spot_options.SingleInstanceType %}
                <singleInstanceType>{{ request.spot_options.SingleInstanceType }}</singleInstanceType>
                {% endif %}
            </spotOptions>
            {% endif %}
            <!-- {'AllocationStrategy': 'lowest-price', 'MaxTotalPrice': '50', 'MinTargetCapacity': 1, 'SingleAvailabilityZone': True, 'SingleInstanceType': True} -->
            {% if request.on_demand_options %}
            <onDemandOptions>
                {% if request.on_demand_options.AllocationStrategy %}
                <allocationStrategy>{{ request.on_demand_options.AllocationStrategy }}</allocationStrategy>
                {% endif %}
                {% if request.on_demand_options.MaxTotalPrice %}
                <maxTotalPrice>{{ request.on_demand_options.MaxTotalPrice }}</maxTotalPrice>
                {% endif %}
                {% if request.on_demand_options.MinTargetCapacity %}
                <minTargetCapacity>{{ request.on_demand_options.MinTargetCapacity }}</minTargetCapacity>
                {% endif %}
                {% if request.on_demand_options.SingleAvailabilityZone %}
                <singleAvailabilityZone>{{ request.on_demand_options.SingleAvailabilityZone }}</singleAvailabilityZone>
                {% endif %}
                {% if request.on_demand_options.SingleInstanceType %}
                <singleInstanceType>{{ request.on_demand_options.SingleInstanceType }}</singleInstanceType>
                {% endif %}
                {% if request.on_demand_options.CapacityReservationOptions %}
                <capacityReservationOptions>
                    {% if request.on_demand_options.CapacityReservationOptions.UsageStrategy %}
                    <usageStrategy>{{ request.on_demand_options.CapacityReservationOptions.UsageStrategy }}</usageStrategy>
                    {% endif %}
                </capacityReservationOptions>
                {% endif %}
            </onDemandOptions>
            {% endif %}
            <terminateInstancesWithExpiration>{{ request.terminate_instances_with_expiration }}</terminateInstancesWithExpiration>
            <type>{{ request.fleet_type }}</type>
            {% if request.valid_from %}
            <validFrom>{{ request.valid_from }}</validFrom>
            {% endif %}
            {% if request.valid_until %}
            <validUntil>{{ request.valid_until }}</validUntil>
            {% endif %}
            <replaceUnhealthyInstances>{{ request.replace_unhealthy_instances }}</replaceUnhealthyInstances>
            <tagSet>
                {% for tag in request.tags %}
                <item>
                    <key>{{ tag.key }}</key>
                    <value>{{ tag.value }}</value>
                </item>
                {% endfor %}
            </tagSet>
        </item>
        {% endfor %}
    </fleetSet>
</DescribeFleetsResponse>"""

DESCRIBE_FLEET_INSTANCES_TEMPLATE = """<DescribeFleetInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2016-09-15/">
    <requestId>cfb09950-45e2-472d-a6a9-example</requestId>
    <fleetId>{{ fleet_id }}</fleetId>
    <activeInstanceSet>
        {% for i in instances %}
        <item>
            <instanceId>{{ i.instance.id }}</instanceId>
            {% if i.id %}
            <spotInstanceRequestId>{{ i.id }}</spotInstanceRequestId>
            {% endif %}
            <instanceType>{{ i.instance.instance_type }}</instanceType>
            <instanceHealth>healthy</instanceHealth>
        </item>
        {% endfor %}
    </activeInstanceSet>
</DescribeFleetInstancesResponse>
"""

DELETE_FLEETS_TEMPLATE = """<DeleteFleetResponse xmlns="http://ec2.amazonaws.com/doc/2016-09-15/">
    <requestId>e12d2fe5-6503-4b4b-911c-example</requestId>
    <unsuccessfulFleetDeletionSet/>
    <successfulFleetDeletionSet>
        {% for fleet in fleets %}
        <item>
            <fleetId>{{ fleet.id }}</fleetId>
            <currentFleetState>{{ fleet.state }}</currentFleetState>
            <previousFleetState>active</previousFleetState>
        </item>
        {% endfor %}
    </successfulFleetDeletionSet>
</DeleteFleetResponse>"""
