# This file is automatically generated by botocraft.  Do not edit directly.
# mypy: disable-error-code="index, override, assignment, union-attr, misc"
from botocraft.mixins.elbv2 import load_balancer_attributes_to_dict
from botocraft.mixins.tags import TagsDictMixin
from botocraft.services.common import Tag
from .abstract import (
    Boto3Model,
    ReadonlyBoto3Model,
    PrimaryBoto3Model,
    ReadonlyPrimaryBoto3Model,
    Boto3ModelManager,
    ReadonlyBoto3ModelManager,
)
from botocraft.services.ec2 import Vpc, VpcManager
from typing import ClassVar, Type, Optional, Literal, Dict, List, Union, Any, cast
from botocraft.services.ec2 import SecurityGroup, SecurityGroupManager
from functools import cached_property
from .abstract import PrimaryBoto3ModelQuerySet
from datetime import datetime
from collections import OrderedDict
from pydantic import Field

# ===============
# Managers
# ===============


class LoadBalancerManager(Boto3ModelManager):
    service_name: str = "elbv2"

    def create(
        self,
        model: "LoadBalancer",
        SubnetMappings: List["SubnetMapping"] | None = None,
        Tags: List[Tag] | None = None,
    ) -> "LoadBalancer":
        """
        Creates an Application Load Balancer, Network Load Balancer, or Gateway Load
        Balancer.

        Args:
            model: The :py:class:`LoadBalancer` to create.

        Keyword Args:
            SubnetMappings: The IDs of the subnets. You can specify only one subnet per Availability Zone. You must specify
                either subnets or subnet mappings, but not both.
            Tags: The tags to assign to the load balancer.
        """
        data = model.model_dump(exclude_none=True, by_alias=True)
        args = dict(
            Name=data.get("LoadBalancerName"),
            Subnets=data.get("Subnets"),
            SubnetMappings=self.serialize(SubnetMappings),
            SecurityGroups=data.get("SecurityGroups"),
            Scheme=data.get("Scheme"),
            Tags=self.serialize(Tags),
            Type=data.get("Type"),
            IpAddressType=data.get("IpAddressType"),
            CustomerOwnedIpv4Pool=data.get("CustomerOwnedIpv4Pool"),
            EnablePrefixForIpv6SourceNat=data.get("EnablePrefixForIpv6SourceNat"),
            IpamPools=data.get("IpamPools"),
        )
        _response = self.client.create_load_balancer(
            **{k: v for k, v in args.items() if v is not None}
        )
        response = CreateLoadBalancerOutput(**_response)

        self.sessionize(response.LoadBalancers[0])
        return cast("LoadBalancer", response.LoadBalancers[0])

    def delete(self, LoadBalancerArn: str) -> None:
        """
        Deletes the specified Application Load Balancer, Network Load Balancer, or
        Gateway Load Balancer. Deleting a load balancer also deletes its listeners.

        Args:
            LoadBalancerArn: The Amazon Resource Name (ARN) of the load balancer.
        """
        args: Dict[str, Any] = dict(LoadBalancerArn=self.serialize(LoadBalancerArn))
        self.client.delete_load_balancer(
            **{k: v for k, v in args.items() if v is not None}
        )

    def get(
        self, *, LoadBalancerArn: str | None = None, Name: str | None = None
    ) -> Optional["LoadBalancer"]:
        """
        Describes the specified load balancers or all of your load balancers.

        Keyword Args:
            LoadBalancerArn: The Amazon Resource Names (ARN) of the load balancer.
            Name: The names of the load balancer.
        """
        args: Dict[str, Any] = dict(
            LoadBalancerArns=self.serialize([LoadBalancerArn]),
            Names=self.serialize([Name]),
        )
        _response = self.client.describe_load_balancers(
            **{k: v for k, v in args.items() if v is not None}
        )
        response = DescribeLoadBalancersOutput(**_response)

        if response and response.LoadBalancers:
            self.sessionize(response.LoadBalancers[0])
            return response.LoadBalancers[0]
        return None

    def list(
        self,
        *,
        LoadBalancerArns: List[str] | None = None,
        Names: List[str] | None = None,
    ) -> PrimaryBoto3ModelQuerySet:
        """
        Describes the specified load balancers or all of your load balancers.

        Keyword Args:
            LoadBalancerArns: The Amazon Resource Names (ARN) of the load balancers. You can specify up to 20 load balancers in
                a single call.
            Names: The names of the load balancers.
        """
        paginator = self.client.get_paginator("describe_load_balancers")
        args: Dict[str, Any] = dict(
            LoadBalancerArns=self.serialize(LoadBalancerArns),
            Names=self.serialize(Names),
        )
        response_iterator = paginator.paginate(
            **{k: v for k, v in args.items() if v is not None}
        )
        results = []
        for _response in response_iterator:
            if list(_response.keys()) == ["ResponseMetadata"]:
                break
            if "ResponseMetadata" in _response:
                del _response["ResponseMetadata"]
            response = DescribeLoadBalancersOutput(**_response)
            if response.LoadBalancers:
                results.extend(response.LoadBalancers)
            else:
                if getattr(response, "NextToken", None):
                    continue
                break
        self.sessionize(results)
        if results and isinstance(results[0], Boto3Model):
            return PrimaryBoto3ModelQuerySet(results)
        return results

    @load_balancer_attributes_to_dict
    def attributes(self, LoadBalancerArn: str) -> List["LoadBalancerAttribute"]:
        """
        Describes the attributes for the specified Application Load Balancer, Network
        Load Balancer, or Gateway Load Balancer.

        Args:
            LoadBalancerArn: The Amazon Resource Name (ARN) of the load balancer.
        """
        args: Dict[str, Any] = dict(LoadBalancerArn=self.serialize(LoadBalancerArn))
        _response = self.client.describe_load_balancer_attributes(
            **{k: v for k, v in args.items() if v is not None}
        )
        response = DescribeLoadBalancerAttributesOutput(**_response)

        results: List["LoadBalancerAttribute"] = None
        if response is not None:
            results = response.Attributes

        self.sessionize(results)
        return cast("List[LoadBalancerAttribute]", results)


class ListenerManager(Boto3ModelManager):
    service_name: str = "elbv2"

    def create(self, model: "Listener", Tags: List[Tag] | None = None) -> "Listener":
        """
        Creates a listener for the specified Application Load Balancer, Network Load
        Balancer, or Gateway Load Balancer.

        Args:
            model: The :py:class:`Listener` to create.

        Keyword Args:
            Tags: The tags to assign to the listener.
        """
        data = model.model_dump(exclude_none=True, by_alias=True)
        args = dict(
            LoadBalancerArn=data.get("LoadBalancerArn"),
            DefaultActions=data.get("DefaultActions"),
            Protocol=data.get("Protocol"),
            Port=data.get("Port"),
            SslPolicy=data.get("SslPolicy"),
            Certificates=data.get("Certificates"),
            AlpnPolicy=data.get("AlpnPolicy"),
            Tags=self.serialize(Tags),
            MutualAuthentication=data.get("MutualAuthentication"),
        )
        _response = self.client.create_listener(
            **{k: v for k, v in args.items() if v is not None}
        )
        response = CreateListenerOutput(**_response)

        self.sessionize(response.Listeners[0])
        return cast("Listener", response.Listeners[0])

    def update(self, model: "Listener") -> "Listener":
        """
        Replaces the specified properties of the specified listener. Any properties that
        you do not specify remain unchanged.

        Args:
            model: The :py:class:`Listener` to update.
        """
        data = model.model_dump(exclude_none=True, by_alias=True)
        args = dict(
            ListenerArn=data.get("ListenerArn"),
            Port=data.get("Port"),
            Protocol=data.get("Protocol"),
            SslPolicy=data.get("SslPolicy"),
            Certificates=data.get("Certificates"),
            DefaultActions=data.get("DefaultActions"),
            AlpnPolicy=data.get("AlpnPolicy"),
            MutualAuthentication=data.get("MutualAuthentication"),
        )
        _response = self.client.modify_listener(
            **{k: v for k, v in args.items() if v is not None}
        )
        response = ModifyListenerOutput(**_response)

        self.sessionize(response.Listeners[0])
        return cast("Listener", response.Listeners[0])

    def delete(self, ListenerArn: str) -> None:
        """
        Deletes the specified listener.

        Args:
            ListenerArn: The Amazon Resource Name (ARN) of the listener.
        """
        args: Dict[str, Any] = dict(ListenerArn=self.serialize(ListenerArn))
        self.client.delete_listener(**{k: v for k, v in args.items() if v is not None})

    def get(self, ListenerArn: str) -> Optional["Listener"]:
        """
        Describes the specified listeners or the listeners for the specified Application
        Load Balancer, Network Load Balancer, or Gateway Load Balancer. You must specify
        either a load balancer or one or more listeners.

        Args:
            ListenerArn: The Amazon Resource Names (ARN) of the listener.
        """
        args: Dict[str, Any] = dict(ListenerArns=self.serialize([ListenerArn]))
        _response = self.client.describe_listeners(
            **{k: v for k, v in args.items() if v is not None}
        )
        response = DescribeListenersOutput(**_response)

        if response and response.Listeners:
            self.sessionize(response.Listeners[0])
            return response.Listeners[0]
        return None

    def list(
        self,
        *,
        LoadBalancerArn: str | None = None,
        ListenerArns: List[str] | None = None,
    ) -> PrimaryBoto3ModelQuerySet:
        """
        Describes the specified listeners or the listeners for the specified Application
        Load Balancer, Network Load Balancer, or Gateway Load Balancer. You must specify
        either a load balancer or one or more listeners.

        Keyword Args:
            LoadBalancerArn: The Amazon Resource Name (ARN) of the load balancer.
            ListenerArns: The Amazon Resource Names (ARN) of the listeners.
        """
        paginator = self.client.get_paginator("describe_listeners")
        args: Dict[str, Any] = dict(
            LoadBalancerArn=self.serialize(LoadBalancerArn),
            ListenerArns=self.serialize(ListenerArns),
        )
        response_iterator = paginator.paginate(
            **{k: v for k, v in args.items() if v is not None}
        )
        results = []
        for _response in response_iterator:
            if list(_response.keys()) == ["ResponseMetadata"]:
                break
            if "ResponseMetadata" in _response:
                del _response["ResponseMetadata"]
            response = DescribeListenersOutput(**_response)
            if response.Listeners:
                results.extend(response.Listeners)
            else:
                if getattr(response, "NextToken", None):
                    continue
                break
        self.sessionize(results)
        if results and isinstance(results[0], Boto3Model):
            return PrimaryBoto3ModelQuerySet(results)
        return results


class RuleManager(Boto3ModelManager):
    service_name: str = "elbv2"

    def create(
        self, model: "Rule", ListenerArn: str, Tags: List[Tag] | None = None
    ) -> "Rule":
        """
        Creates a rule for the specified listener. The listener must be associated with
        an Application Load Balancer.

        Args:
            model: The :py:class:`Rule` to create.
            ListenerArn: The Amazon Resource Name (ARN) of the listener.

        Keyword Args:
            Tags: The tags to assign to the rule.
        """
        data = model.model_dump(exclude_none=True, by_alias=True)
        args = dict(
            ListenerArn=self.serialize(ListenerArn),
            Conditions=data.get("Conditions"),
            Priority=data.get("Priority"),
            Actions=data.get("Actions"),
            Tags=self.serialize(Tags),
        )
        _response = self.client.create_rule(
            **{k: v for k, v in args.items() if v is not None}
        )
        response = CreateRuleOutput(**_response)

        self.sessionize(response.Rules[0])
        return cast("Rule", response.Rules[0])

    def update(self, model: "Rule") -> "Rule":
        """
        Replaces the specified properties of the specified rule. Any properties that you
        do not specify are unchanged.

        Args:
            model: The :py:class:`Rule` to update.
        """
        data = model.model_dump(exclude_none=True, by_alias=True)
        args = dict(
            RuleArn=data.get("RuleArn"),
            Conditions=data.get("Conditions"),
            Actions=data.get("Actions"),
        )
        _response = self.client.modify_rule(
            **{k: v for k, v in args.items() if v is not None}
        )
        response = ModifyRuleOutput(**_response)

        self.sessionize(response.Rules[0])
        return cast("Rule", response.Rules[0])

    def delete(self, RuleArn: str) -> None:
        """
        Deletes the specified rule.

        Args:
            RuleArn: The Amazon Resource Name (ARN) of the rule.
        """
        args: Dict[str, Any] = dict(RuleArn=self.serialize(RuleArn))
        self.client.delete_rule(**{k: v for k, v in args.items() if v is not None})

    def get(self, RuleArn: str) -> Optional["Rule"]:
        """
        Describes the specified rules or the rules for the specified listener. You must
        specify either a listener or one or more rules.

        Args:
            RuleArn: The Amazon Resource Names (ARN) of the rule.
        """
        args: Dict[str, Any] = dict(RuleArns=self.serialize([RuleArn]))
        _response = self.client.describe_rules(
            **{k: v for k, v in args.items() if v is not None}
        )
        response = DescribeRulesOutput(**_response)

        if response and response.Rules:
            self.sessionize(response.Rules[0])
            return response.Rules[0]
        return None

    def list(
        self, *, ListenerArn: str | None = None, RuleArns: List[str] | None = None
    ) -> PrimaryBoto3ModelQuerySet:
        """
        Describes the specified rules or the rules for the specified listener. You must
        specify either a listener or one or more rules.

        Keyword Args:
            ListenerArn: The Amazon Resource Name (ARN) of the listener.
            RuleArns: The Amazon Resource Names (ARN) of the rules.
        """
        paginator = self.client.get_paginator("describe_rules")
        args: Dict[str, Any] = dict(
            ListenerArn=self.serialize(ListenerArn), RuleArns=self.serialize(RuleArns)
        )
        response_iterator = paginator.paginate(
            **{k: v for k, v in args.items() if v is not None}
        )
        results = []
        for _response in response_iterator:
            if list(_response.keys()) == ["ResponseMetadata"]:
                break
            if "ResponseMetadata" in _response:
                del _response["ResponseMetadata"]
            response = DescribeRulesOutput(**_response)
            if response.Rules:
                results.extend(response.Rules)
            else:
                if getattr(response, "NextToken", None):
                    continue
                break
        self.sessionize(results)
        if results and isinstance(results[0], Boto3Model):
            return PrimaryBoto3ModelQuerySet(results)
        return results


class TargetGroupManager(Boto3ModelManager):
    service_name: str = "elbv2"

    def create(
        self, model: "TargetGroup", Name: str, Tags: List[Tag] | None = None
    ) -> "TargetGroup":
        """
        Creates a target group.

        Args:
            model: The :py:class:`TargetGroup` to create.
            Name: The name of the target group.

        Keyword Args:
            Tags: The tags to assign to the target group.
        """
        data = model.model_dump(exclude_none=True, by_alias=True)
        args = dict(
            Name=self.serialize(Name),
            Protocol=data.get("Protocol"),
            ProtocolVersion=data.get("ProtocolVersion"),
            Port=data.get("Port"),
            VpcId=data.get("VpcId"),
            HealthCheckProtocol=data.get("HealthCheckProtocol"),
            HealthCheckPort=data.get("HealthCheckPort"),
            HealthCheckEnabled=data.get("HealthCheckEnabled"),
            HealthCheckPath=data.get("HealthCheckPath"),
            HealthCheckIntervalSeconds=data.get("HealthCheckIntervalSeconds"),
            HealthCheckTimeoutSeconds=data.get("HealthCheckTimeoutSeconds"),
            HealthyThresholdCount=data.get("HealthyThresholdCount"),
            UnhealthyThresholdCount=data.get("UnhealthyThresholdCount"),
            Matcher=data.get("Matcher"),
            TargetType=data.get("TargetType"),
            Tags=self.serialize(Tags),
            IpAddressType=data.get("IpAddressType"),
        )
        _response = self.client.create_target_group(
            **{k: v for k, v in args.items() if v is not None}
        )
        response = CreateTargetGroupOutput(**_response)

        self.sessionize(response.TargetGroups[0])
        return cast("TargetGroup", response.TargetGroups[0])

    def update(self, model: "TargetGroup") -> "TargetGroup":
        """
        Modifies the health checks used when evaluating the health state of the targets
        in the specified target group.

        Args:
            model: The :py:class:`TargetGroup` to update.
        """
        data = model.model_dump(exclude_none=True, by_alias=True)
        args = dict(
            TargetGroupArn=data.get("TargetGroupArn"),
            HealthCheckProtocol=data.get("HealthCheckProtocol"),
            HealthCheckPort=data.get("HealthCheckPort"),
            HealthCheckPath=data.get("HealthCheckPath"),
            HealthCheckEnabled=data.get("HealthCheckEnabled"),
            HealthCheckIntervalSeconds=data.get("HealthCheckIntervalSeconds"),
            HealthCheckTimeoutSeconds=data.get("HealthCheckTimeoutSeconds"),
            HealthyThresholdCount=data.get("HealthyThresholdCount"),
            UnhealthyThresholdCount=data.get("UnhealthyThresholdCount"),
            Matcher=data.get("Matcher"),
        )
        _response = self.client.modify_target_group(
            **{k: v for k, v in args.items() if v is not None}
        )
        response = ModifyTargetGroupOutput(**_response)

        self.sessionize(response.TargetGroups[0])
        return cast("TargetGroup", response.TargetGroups[0])

    def delete(self, TargetGroupArn: str) -> None:
        """
        Deletes the specified target group.

        Args:
            TargetGroupArn: The Amazon Resource Name (ARN) of the target group.
        """
        args: Dict[str, Any] = dict(TargetGroupArn=self.serialize(TargetGroupArn))
        self.client.delete_target_group(
            **{k: v for k, v in args.items() if v is not None}
        )

    def get(
        self, *, TargetGroupArn: str | None = None, Name: str | None = None
    ) -> Optional["TargetGroup"]:
        """
        Describes the specified target groups or all of your target groups. By default,
        all target groups are described. Alternatively, you can specify one of the
        following to filter the results: the ARN of the load balancer, the names of one
        or more target groups, or the ARNs of one or more target groups.

        Keyword Args:
            TargetGroupArn: The Amazon Resource Names (ARN) of the target group.
            Name: The name of the target group.
        """
        args: Dict[str, Any] = dict(
            TargetGroupArns=self.serialize([TargetGroupArn]),
            Names=self.serialize([Name]),
        )
        _response = self.client.describe_target_groups(
            **{k: v for k, v in args.items() if v is not None}
        )
        response = DescribeTargetGroupsOutput(**_response)

        if response and response.TargetGroups:
            self.sessionize(response.TargetGroups[0])
            return response.TargetGroups[0]
        return None

    def list(
        self,
        *,
        LoadBalancerArn: str | None = None,
        TargetGroupArns: List[str] | None = None,
        Names: List[str] | None = None,
    ) -> PrimaryBoto3ModelQuerySet:
        """
        Describes the specified target groups or all of your target groups. By default,
        all target groups are described. Alternatively, you can specify one of the
        following to filter the results: the ARN of the load balancer, the names of one
        or more target groups, or the ARNs of one or more target groups.

        Keyword Args:
            LoadBalancerArn: The Amazon Resource Name (ARN) of the load balancer.
            TargetGroupArns: The Amazon Resource Names (ARN) of the target groups.
            Names: The names of the target groups.
        """
        paginator = self.client.get_paginator("describe_target_groups")
        args: Dict[str, Any] = dict(
            LoadBalancerArn=self.serialize(LoadBalancerArn),
            TargetGroupArns=self.serialize(TargetGroupArns),
            Names=self.serialize(Names),
        )
        response_iterator = paginator.paginate(
            **{k: v for k, v in args.items() if v is not None}
        )
        results = []
        for _response in response_iterator:
            if list(_response.keys()) == ["ResponseMetadata"]:
                break
            if "ResponseMetadata" in _response:
                del _response["ResponseMetadata"]
            response = DescribeTargetGroupsOutput(**_response)
            if response.TargetGroups:
                results.extend(response.TargetGroups)
            else:
                if getattr(response, "NextToken", None):
                    continue
                break
        self.sessionize(results)
        if results and isinstance(results[0], Boto3Model):
            return PrimaryBoto3ModelQuerySet(results)
        return results

    def targets(
        self,
        TargetGroupArn: str,
        *,
        Targets: List["TargetDescription"] | None = None,
        Include: List[Literal["AnomalyDetection", "All"]] | None = None,
    ) -> List["TargetHealthDescription"] | None:
        """
        Describes the health of the specified targets or all of your targets.

        Args:
            TargetGroupArn: The Amazon Resource Name (ARN) of the target group.

        Keyword Args:
            Targets: The targets.
            Include: Used to include anomaly detection information.
        """
        args: Dict[str, Any] = dict(
            TargetGroupArn=self.serialize(TargetGroupArn),
            Targets=self.serialize(Targets),
            Include=self.serialize(Include),
        )
        _response = self.client.describe_target_health(
            **{k: v for k, v in args.items() if v is not None}
        )
        response = DescribeTargetHealthOutput(**_response)

        results: List["TargetHealthDescription"] | None = None
        if response is not None:
            results = response.TargetHealthDescriptions

        self.sessionize(results)
        return cast("List[TargetHealthDescription] | None", results)


# ==============
# Service Models
# ==============


class LoadBalancerState(Boto3Model):
    """
    Information about the state of the load balancer.
    """

    Code: Literal["active", "provisioning", "active_impaired", "failed"] | None = (
        None
    )
    """
    The state code.

    The initial state of the load balancer is ``provisioning``. After the load balancer is fully set up and
    ready to route traffic, its state is ``active``. If load balancer is routing traffic but does not have the resources it
    needs to scale, its state is``active_impaired``. If the load balancer could not be set up, its state is ``failed``.
    """
    Reason: str | None = None
    """
    A description of the state.
    """


class LoadBalancerAddress(Boto3Model):
    """
    Information about a static IP address for a load balancer.
    """

    IpAddress: str | None = None
    """
    The static IP address.
    """
    AllocationId: str | None = None
    """
    [Network Load Balancers] The allocation ID of the Elastic IP address for an
    internal-facing load balancer.
    """
    PrivateIPv4Address: str | None = None
    """
    [Network Load Balancers] The private IPv4 address for an internal load balancer.
    """
    IPv6Address: str | None = None
    """
    [Network Load Balancers] The IPv6 address.
    """


class AvailabilityZone(Boto3Model):
    """
    Information about an Availability Zone.
    """

    ZoneName: str | None = None
    """
    The name of the Availability Zone.
    """
    SubnetId: str | None = None
    """
    The ID of the subnet.

    You can specify one subnet per Availability Zone.
    """
    OutpostId: str | None = None
    """
    [Application Load Balancers on Outposts] The ID of the Outpost.
    """
    LoadBalancerAddresses: List["LoadBalancerAddress"] | None = None
    """
    [Network Load Balancers] If you need static IP addresses for your load balancer, you
    can specify one Elastic IP address per Availability Zone when you create an
    internal-facing load balancer.

    For internal load balancers, you can specify a private IP address from the IPv4
    range of the subnet.
    """
    SourceNatIpv6Prefixes: List[str] | None = None
    """
    [Network Load Balancers with UDP listeners] The IPv6 prefixes to use for source NAT.

    For each subnet, specify an IPv6
    prefix (/80 netmask) from the subnet CIDR block or ``auto_assigned`` to use an IPv6 prefix selected at random from the
    subnet CIDR block.
    """


class ElbV2IpamPools(Boto3Model):
    """
    An IPAM pool is a collection of IP address CIDRs.

    IPAM pools enable you to organize your IP addresses according to your routing and
    security needs.
    """

    Ipv4IpamPoolId: str | None = None
    """
    The ID of the IPv4 IPAM pool.
    """


class LoadBalancer(PrimaryBoto3Model):
    """
    Information about a load balancer.
    """

    manager_class: ClassVar[Type[Boto3ModelManager]] = LoadBalancerManager

    LoadBalancerName: str
    """
    The name of the load balancer.
    """
    Scheme: Literal["internet-facing", "internal"] | None = "internet-facing"
    """
    The nodes of an Internet-facing load balancer have public IP addresses.

    The DNS name of an Internet-facing load balancer is publicly resolvable to the
    public IP addresses of the nodes. Therefore, Internet-facing load balancers can
    route requests from clients over the internet.
    """
    Type: Literal["application", "network", "gateway"] | None = "application"
    """
    The type of load balancer.
    """
    IpAddressType: Literal["ipv4", "dualstack", "dualstack-without-public-ipv4"] | None = "ipv4"
    """
    The type of IP addresses used for public or private connections by the subnets
    attached to your load balancer.
    """
    LoadBalancerArn: str = Field(default=None, frozen=True)
    """
    The Amazon Resource Name (ARN) of the load balancer.
    """
    DNSName: str = Field(default=None, frozen=True)
    """
    The public DNS name of the load balancer.
    """
    CanonicalHostedZoneId: str = Field(default=None, frozen=True)
    """
    The ID of the Amazon Route 53 hosted zone associated with the load balancer.
    """
    CreatedTime: datetime = Field(default=None, frozen=True)
    """
    The date and time the load balancer was created.
    """
    VpcId: str = Field(default=None, frozen=True)
    """
    The ID of the VPC for the load balancer.
    """
    State: LoadBalancerState = Field(default=None, frozen=True)
    """
    The state of the load balancer.
    """
    AvailabilityZones: List["AvailabilityZone"] = Field(
        default_factory=list, frozen=True
    )
    """
    The subnets for the load balancer.
    """
    SecurityGroups: List[str] | None = None
    """
    The IDs of the security groups for the load balancer.
    """
    CustomerOwnedIpv4Pool: str | None = None
    """
    [Application Load Balancers on Outposts] The ID of the customer-owned address pool.
    """
    EnforceSecurityGroupInboundRulesOnPrivateLinkTraffic: str = Field(
        default=None, frozen=True
    )
    """
    Indicates whether to evaluate inbound security group rules for traffic sent to a
    Network Load Balancer through Amazon Web Services PrivateLink.
    """
    EnablePrefixForIpv6SourceNat: Literal["on", "off"] | None = None
    """
    [Network Load Balancers with UDP listeners] Indicates whether to use an IPv6 prefix
    from each subnet for source NAT.

    The
    IP address type must be ``dualstack``. The default value is ``off``.
    """
    IpamPools: ElbV2IpamPools | None = None
    """
    [Application Load Balancers] The IPAM pool in use by the load balancer, if
    configured.
    """

    @property
    def pk(self) -> str | None:
        """
        Return the primary key of the model.   This is the value of the
        :py:attr:`LoadBalancerArn` attribute.

        Returns:
            The primary key of the model instance.
        """
        return self.LoadBalancerArn

    @property
    def arn(self) -> str | None:
        """
        Return the ARN of the model.   This is the value of the
        :py:attr:`LoadBalancerArn` attribute.

        Returns:
            The ARN of the model instance.
        """
        return self.LoadBalancerArn

    @property
    def name(self) -> str | None:
        """
        Return the name of the model.   This is the value of the
        :py:attr:`LoadBalancerName` attribute.

        Returns:
            The name of the model instance.
        """
        return self.LoadBalancerName

    def __hash__(self) -> int:
        """
        Return the hash of the model.

        This is the value of the
        :py:attr:`LoadBalancerArn` attribute.
        """
        return hash(self.LoadBalancerArn)

    @property
    def logging_enabled(self) -> bool:
        """
        Return whether logging is enabled for the load balancer.
        """

        return self.attributes().get("access_logs.s3.enabled") == "true"

    @property
    def logging_bucket(self) -> str:
        """
        Return the name of the S3 bucket that logs are stored in, if any.
        """

        return self.attributes().get("access_logs.s3.bucket")

    @property
    def logging_prefix(self) -> str:
        """
        Return the prefix in the S3 bucket that logs are stored in, if any.
        """

        return self.attributes().get("access_logs.s3.prefix")

    @cached_property
    def listeners(self) -> List["Listener"] | None:
        """
        Return the ARNs of :py:class:`Listener` objects that belong to this load
        balancer, if any.

        .. note::

            The output of this property is cached on the model instance, so
            calling this multiple times will not result in multiple calls to the
            AWS API.   If you need a fresh copy of the data, you can re-get the
            model instance from the manager.
        """

        try:
            pk = OrderedDict(
                {
                    "load_balancer": self.LoadBalancerArn,
                }
            )
        except AttributeError:
            return []
        return Listener.objects.using(self.session).list(**pk)  # type: ignore[arg-type]

    @cached_property
    def vpc(self) -> Optional["Vpc"]:
        """
        Return the :py:class:`Vpc` object that this load balancer belongs to, if any.

        .. note::

            The output of this property is cached on the model instance, so
            calling this multiple times will not result in multiple calls to the
            AWS API.   If you need a fresh copy of the data, you can re-get the
            model instance from the manager.
        """

        try:
            pk = OrderedDict(
                {
                    "VpcId": self.VpcId,
                }
            )
        except AttributeError:
            return None
        return Vpc.objects.using(self.session).get(**pk)  # type: ignore[arg-type]

    @cached_property
    def security_groups(self) -> List["SecurityGroup"] | None:
        """
        Return the ARNs of :py:class:`SecurityGroup` objects that belong to this load
        balancer, if any.

        .. note::

            The output of this property is cached on the model instance, so
            calling this multiple times will not result in multiple calls to the
            AWS API.   If you need a fresh copy of the data, you can re-get the
            model instance from the manager.
        """

        try:
            pk = OrderedDict(
                {
                    "GroupIds": self.SecurityGroups,
                }
            )
        except AttributeError:
            return []
        return SecurityGroup.objects.using(self.session).list(**pk)  # type: ignore[arg-type]

    def attributes(self) -> List["LoadBalancerAttribute"]:
        """
        Return the attributes of the load balancer.

        These are stored separately from the load balancer object
        """

        return (
            cast("LoadBalancerManager", self.objects)  # type: ignore[attr-defined]
            .using(self.session)
            .attributes(
                cast("str", self.arn),
            )
        )


class Certificate(ReadonlyBoto3Model):
    """
    Information about an SSL server certificate.
    """

    CertificateArn: str | None = None
    """
    The Amazon Resource Name (ARN) of the certificate.
    """
    IsDefault: bool | None = None
    """
    Indicates whether the certificate is the default certificate.

    Do not set this value when specifying a certificate as an input. This value is not
    included in the output when describing a listener, but is included when describing
    listener certificates.
    """


class AuthenticateOidcActionConfig(Boto3Model):
    """
    Request parameters when using an identity provider (IdP) that is compliant with
    OpenID Connect (OIDC) to authenticate users.
    """

    Issuer: str
    """
    The OIDC issuer identifier of the IdP.

    This must be a full URL, including the HTTPS protocol, the domain, and the path.
    """
    AuthorizationEndpoint: str
    """
    The authorization endpoint of the IdP.

    This must be a full URL, including the HTTPS protocol, the domain, and the path.
    """
    TokenEndpoint: str
    """
    The token endpoint of the IdP.

    This must be a full URL, including the HTTPS protocol, the domain, and the path.
    """
    UserInfoEndpoint: str
    """
    The user info endpoint of the IdP.

    This must be a full URL, including the HTTPS protocol, the domain, and the path.
    """
    ClientId: str
    """
    The OAuth 2.0 client identifier.
    """
    ClientSecret: str | None = None
    """
    The OAuth 2.0 client secret.

    This parameter is required if you are creating a rule. If you are modifying a rule, you can
    omit this parameter if you set ``UseExistingClientSecret`` to true.
    """
    SessionCookieName: str | None = None
    """
    The name of the cookie used to maintain session information.

    The default is AWSELBAuthSessionCookie.
    """
    Scope: str | None = None
    """
    The set of user claims to be requested from the IdP.

    The default is ``openid``.
    """
    SessionTimeout: int | None = None
    """
    The maximum duration of the authentication session, in seconds.

    The default is 604800 seconds (7 days).
    """
    AuthenticationRequestExtraParams: Dict[str, str] | None = None
    """
    The query parameters (up to 10) to include in the redirect request to the
    authorization endpoint.
    """
    OnUnauthenticatedRequest: Literal["deny", "allow", "authenticate"] | None = None
    """
    The behavior if the user is not authenticated.

    The following are possible values:
    """
    UseExistingClientSecret: bool | None = None
    """
    Indicates whether to use the existing client secret when modifying a rule.

    If you are creating a rule, you can omit this parameter or set it to false.
    """


class AuthenticateCognitoActionConfig(Boto3Model):
    """
    Request parameters to use when integrating with Amazon Cognito to authenticate
    users.
    """

    UserPoolArn: str
    """
    The Amazon Resource Name (ARN) of the Amazon Cognito user pool.
    """
    UserPoolClientId: str
    """
    The ID of the Amazon Cognito user pool client.
    """
    UserPoolDomain: str
    """
    The domain prefix or fully-qualified domain name of the Amazon Cognito user pool.
    """
    SessionCookieName: str | None = None
    """
    The name of the cookie used to maintain session information.

    The default is AWSELBAuthSessionCookie.
    """
    Scope: str | None = None
    """
    The set of user claims to be requested from the IdP.

    The default is ``openid``.
    """
    SessionTimeout: int | None = None
    """
    The maximum duration of the authentication session, in seconds.

    The default is 604800 seconds (7 days).
    """
    AuthenticationRequestExtraParams: Dict[str, str] | None = None
    """
    The query parameters (up to 10) to include in the redirect request to the
    authorization endpoint.
    """
    OnUnauthenticatedRequest: Literal["deny", "allow", "authenticate"] | None = None
    """
    The behavior if the user is not authenticated.

    The following are possible values:
    """


class RedirectActionConfig(Boto3Model):
    """
    Information about a redirect action.

    A URI consists of the following components: protocol://hostname:port/path?query. You must modify at least one of the
    following components to avoid a redirect loop: protocol, hostname, port, or path. Any components that you do not modify
    retain their original values.

    You can reuse URI components using the following reserved keywords:

    * #{protocol}
    * #{host}
    * #{port}
    * #{path} (the leading "/" is removed)
    * #{query}

    For example, you can change the path to "/new/#{path}", the hostname to "example.#{host}", or the query to
    "#{query}&value=xyz".
    """

    Protocol: str | None = None
    """
    The protocol.

    You can specify HTTP, HTTPS, or #{protocol}. You can redirect HTTP to HTTP, HTTP to
    HTTPS, and HTTPS to HTTPS. You can't redirect HTTPS to HTTP.
    """
    Port: str | None = None
    """
    The port.

    You can specify a value from 1 to 65535 or #{port}.
    """
    Host: str | None = None
    """
    The hostname.

    This component is not percent-encoded. The hostname can contain #{host}.
    """
    Path: str | None = None
    """
    The absolute path, starting with the leading "/".

    This component is not percent-encoded. The path can contain #{host}, #{path}, and
    #{port}.
    """
    Query: str | None = None
    """
    The query parameters, URL-encoded when necessary, but not percent-encoded.

    Do not include the leading "?", as it is automatically added. You can specify any of
    the reserved keywords.
    """
    StatusCode: Literal["HTTP_301", "HTTP_302"]
    """
    The HTTP redirect code.

    The redirect is either permanent (HTTP 301) or temporary (HTTP 302).
    """


class FixedResponseActionConfig(Boto3Model):
    """
    Information about an action that returns a custom HTTP response.
    """

    MessageBody: str | None = None
    """
    The message.
    """
    StatusCode: str
    """
    The HTTP response code (2XX, 4XX, or 5XX).
    """
    ContentType: str | None = None
    """
    The content type.
    """


class TargetGroupTuple(Boto3Model):
    """
    Information about how traffic will be distributed between multiple target groups in
    a forward rule.
    """

    TargetGroupArn: str | None = None
    """
    The Amazon Resource Name (ARN) of the target group.
    """
    Weight: int | None = None
    """
    The weight.

    The range is 0 to 999.
    """


class ElbV2TargetGroupStickinessConfig(Boto3Model):
    """
    Information about the target group stickiness for a rule.
    """

    Enabled: bool | None = None
    """
    Indicates whether target group stickiness is enabled.
    """
    DurationSeconds: int | None = None
    """
    The time period, in seconds, during which requests from a client should be routed to
    the same target group.

    The range is 1-604800 seconds (7 days). You must specify this value when enabling
    target group stickiness.
    """


class ForwardActionConfig(Boto3Model):
    """
    Information about a forward action.
    """

    TargetGroups: List["TargetGroupTuple"] | None = None
    """
    The target groups.

    For Network Load Balancers, you can specify a single target group.
    """
    TargetGroupStickinessConfig: ElbV2TargetGroupStickinessConfig | None = None
    """
    The target group stickiness for the rule.
    """


class Action(Boto3Model):
    """
    Information about an action.

    Each rule must include exactly one of the following types of actions: ``forward``, ``fixed-response``, or ``redirect``,
    and it must be the last action to be performed.
    """

    ActionType: Literal[
        "forward",
        "authenticate-oidc",
        "authenticate-cognito",
        "redirect",
        "fixed-response",
    ] = Field(default=None, alias="Type")
    """
    The type of action.
    """
    TargetGroupArn: str | None = None
    """
    The Amazon Resource Name (ARN) of the target group.

    Specify only when ``Type`` is ``forward`` and you want to route to a
    single target group. To route to one or more target groups, use ``ForwardConfig`` instead.
    """
    AuthenticateOidcConfig: AuthenticateOidcActionConfig | None = None
    """
    [HTTPS listeners] Information about an identity provider that is compliant with
    OpenID Connect (OIDC).

    Specify only when
    ``Type`` is ``authenticate-oidc``.
    """
    AuthenticateCognitoConfig: AuthenticateCognitoActionConfig | None = None
    """
    [HTTPS listeners] Information for using Amazon Cognito to authenticate users.

    Specify only when ``Type`` is
    ``authenticate-cognito``.
    """
    Order: int | None = None
    """
    The order for the action.

    This value is required for rules with multiple actions. The action with the lowest
    value for order is performed first.
    """
    RedirectConfig: RedirectActionConfig | None = None
    """
    [Application Load Balancer] Information for creating a redirect action.

    Specify only when ``Type`` is ``redirect``.
    """
    FixedResponseConfig: FixedResponseActionConfig | None = None
    """
    [Application Load Balancer] Information for creating an action that returns a custom
    HTTP response.

    Specify only when
    ``Type`` is ``fixed-response``.
    """
    ForwardConfig: ForwardActionConfig | None = None
    """
    Information for creating an action that distributes requests among one or more
    target groups.

    For Network Load
    Balancers, you can specify a single target group. Specify only when ``Type`` is ``forward``. If you specify both
    ``ForwardConfig`` and ``TargetGroupArn``, you can specify only one target group using ``ForwardConfig`` and it must be
    the same target group specified in ``TargetGroupArn``.
    """


class MutualAuthenticationAttributes(Boto3Model):
    """
    Information about the mutual authentication attributes of a listener.
    """

    Mode: str | None = None
    """
    The client certificate handling method.

    Options are ``off``, ``passthrough`` or ``verify``. The default value is
    ``off``.
    """
    TrustStoreArn: str | None = None
    """
    The Amazon Resource Name (ARN) of the trust store.
    """
    IgnoreClientCertificateExpiry: bool | None = None
    """
    Indicates whether expired client certificates are ignored.
    """
    TrustStoreAssociationStatus: Literal["active", "removed"] | None = None
    """
    Indicates a shared trust stores association status.
    """
    AdvertiseTrustStoreCaNames: Literal["on", "off"] | None = None
    """
    Indicates whether trust store CA certificate names are advertised.
    """


class Listener(PrimaryBoto3Model):
    """
    Information about a listener.
    """

    manager_class: ClassVar[Type[Boto3ModelManager]] = ListenerManager

    LoadBalancerArn: str
    """
    The Amazon Resource Name (ARN) of the load balancer.
    """
    Port: int
    """
    The port on which the load balancer is listening.
    """
    Protocol: Literal["HTTP", "HTTPS", "TCP", "TLS", "UDP", "TCP_UDP", "GENEVE"] | None = "HTTPS"
    """
    The protocol for connections from clients to the load balancer.
    """
    ListenerArn: str | None = None
    """
    The Amazon Resource Name (ARN) of the listener.
    """
    Certificates: List["Certificate"] | None = None
    """
    [HTTPS or TLS listener] The default certificate for the listener.
    """
    SslPolicy: str | None = None
    """
    [HTTPS or TLS listener] The security policy that defines which protocols and ciphers
    are supported.
    """
    DefaultActions: List["Action"] | None = None
    """
    The default actions for the listener.
    """
    AlpnPolicy: List[str] | None = None
    """
    [TLS listener] The name of the Application-Layer Protocol Negotiation (ALPN) policy.
    """
    MutualAuthentication: MutualAuthenticationAttributes | None = None
    """
    The mutual authentication configuration information.
    """

    @property
    def pk(self) -> str | None:
        """
        Return the primary key of the model.   This is the value of the
        :py:attr:`ListenerArn` attribute.

        Returns:
            The primary key of the model instance.
        """
        return self.ListenerArn

    @property
    def arn(self) -> str | None:
        """
        Return the ARN of the model.   This is the value of the :py:attr:`ListenerArn`
        attribute.

        Returns:
            The ARN of the model instance.
        """
        return self.ListenerArn

    def __hash__(self) -> int:
        """
        Return the hash of the model.

        This is the value of the
        :py:attr:`ListenerArn` attribute.
        """
        return hash(self.ListenerArn)

    @cached_property
    def load_balancer(self) -> Optional["LoadBalancer"]:
        """
        Return the :py:class:`LoadBalancer` object that this listener belongs to, if
        any.

        .. note::

            The output of this property is cached on the model instance, so
            calling this multiple times will not result in multiple calls to the
            AWS API.   If you need a fresh copy of the data, you can re-get the
            model instance from the manager.
        """

        try:
            pk = OrderedDict(
                {
                    "LoadBalancerArn": self.LoadBalancerArn,
                }
            )
        except AttributeError:
            return None
        return LoadBalancer.objects.using(self.session).get(**pk)  # type: ignore[arg-type]

    @cached_property
    def rules(self) -> List["Rule"] | None:
        """
        Return the ARNs of :py:class:`Rule` objects that belong to this listener, if
        any.

        .. note::

            The output of this property is cached on the model instance, so
            calling this multiple times will not result in multiple calls to the
            AWS API.   If you need a fresh copy of the data, you can re-get the
            model instance from the manager.
        """

        try:
            pk = OrderedDict(
                {
                    "ListenerArn": self.ListenerArn,
                }
            )
        except AttributeError:
            return []
        return Rule.objects.using(self.session).list(**pk)  # type: ignore[arg-type]


class HostHeaderConditionConfig(Boto3Model):
    """
    Information about a host header condition.
    """

    Values: List[str] | None = None
    """
    The host names.

    The maximum size of each name is 128 characters. The comparison is case insensitive. The following
    wildcard characters are supported: * (matches 0 or more characters) and ? (matches exactly 1 character). You must
    include at least one "." character. You can include only alphabetical characters after the final "." character.
    """


class PathPatternConditionConfig(Boto3Model):
    """
    Information about a path pattern condition.
    """

    Values: List[str] | None = None
    """
    The path patterns to compare against the request URL.

    The maximum size of each string is 128 characters. The comparison is case sensitive.
    The following wildcard characters are supported: * (matches 0 or more characters)
    and ? (matches exactly 1 character).
    """


class HttpHeaderConditionConfig(Boto3Model):
    """
    Information about an HTTP header condition.

    There is a set of standard HTTP header fields. You can also define custom HTTP
    header fields.
    """

    HttpHeaderName: str | None = None
    """
    The name of the HTTP header field.

    The maximum size is 40 characters. The header name is case insensitive. The allowed
    characters are specified by RFC 7230. Wildcards are not supported.
    """
    Values: List[str] | None = None
    """
    The strings to compare against the value of the HTTP header.

    The maximum size of each string is 128 characters. The comparison strings are case
    insensitive. The following wildcard characters are supported: * (matches 0 or more
    characters) and ? (matches exactly 1 character).
    """


class QueryStringKeyValuePair(Boto3Model):
    """
    Information about a key/value pair.
    """

    Key: str | None = None
    """
    The key.

    You can omit the key.
    """
    Value: str | None = None
    """
    The value.
    """


class QueryStringConditionConfig(Boto3Model):
    """
    Information about a query string condition.

    The query string component of a URI starts after the first '?' character and is
    terminated by either a '#' character or the end of the URI. A typical query string
    contains key/value pairs separated by '&' characters. The allowed characters are
    specified by RFC 3986. Any character can be percentage encoded.
    """

    Values: List["QueryStringKeyValuePair"] | None = None
    """
    The key/value pairs or values to find in the query string.

    The maximum size of each string is 128 characters. The
    comparison is case insensitive. The following wildcard characters are supported: * (matches 0 or more characters) and ?
    (matches exactly 1 character). To search for a literal '*' or '?' character in a query string, you must escape these
    characters in ``Values`` using a '' character.
    """


class HttpRequestMethodConditionConfig(Boto3Model):
    """
    Information about an HTTP method condition.

    HTTP defines a set of request methods, also referred to as HTTP verbs. For more
    information, see the
    `HTTP Method Registry <https://www.iana.org/assignments/http-methods/http-methods.xhtml>`_.
    You can also define custom HTTP methods.
    """

    Values: List[str] | None = None
    """
    The name of the request method.

    The maximum size is 40 characters. The allowed characters are A-Z, hyphen (-), and
    underscore (_). The comparison is case sensitive. Wildcards are not supported;
    therefore, the method name must be an exact match.
    """


class SourceIpConditionConfig(Boto3Model):
    """
    Information about a source IP condition.

    You can use this condition to route based on the IP address of the source that
    connects to the load balancer. If a client is behind a proxy, this is the IP address
    of the proxy not the IP address of the client.
    """

    Values: List[str] | None = None
    """
    The source IP addresses, in CIDR format.

    You can use both IPv4 and IPv6 addresses. Wildcards are not supported.
    """


class RuleCondition(Boto3Model):
    """
    Information about a condition for a rule.

    Each rule can optionally include up to one of each of the following conditions: ``http-request-method``, ``host-
    header``, ``path-pattern``, and ``source-ip``. Each rule can also optionally include one or more of each of the
    following conditions: ``http-header`` and ``query-string``. Note that the value for a condition can't be empty.

    For more information, see `Quotas for your Application Load
    Balancers <https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-limits.html>`_.
    """

    FieldName: str = Field(default=None, alias="Field")
    """
    The field in the HTTP request.

    The following are the possible values:
    """
    Values: List[str] | None = None
    """
    The condition value.

    Specify only when ``Field`` is ``host-header`` or ``path-pattern``. Alternatively, to specify
    multiple host names or multiple path patterns, use ``HostHeaderConfig`` or ``PathPatternConfig``.
    """
    HostHeaderConfig: HostHeaderConditionConfig | None = None
    """
    Information for a host header condition.

    Specify only when ``Field`` is ``host-header``.
    """
    PathPatternConfig: PathPatternConditionConfig | None = None
    """
    Information for a path pattern condition.

    Specify only when ``Field`` is ``path-pattern``.
    """
    HttpHeaderConfig: HttpHeaderConditionConfig | None = None
    """
    Information for an HTTP header condition.

    Specify only when ``Field`` is ``http-header``.
    """
    QueryStringConfig: QueryStringConditionConfig | None = None
    """
    Information for a query string condition.

    Specify only when ``Field`` is ``query-string``.
    """
    HttpRequestMethodConfig: HttpRequestMethodConditionConfig | None = None
    """
    Information for an HTTP method condition.

    Specify only when ``Field`` is ``http-request-method``.
    """
    SourceIpConfig: SourceIpConditionConfig | None = None
    """
    Information for a source IP condition.

    Specify only when ``Field`` is ``source-ip``.
    """


class Rule(PrimaryBoto3Model):
    """
    Information about a rule.
    """

    manager_class: ClassVar[Type[Boto3ModelManager]] = RuleManager

    Priority: str | None = "1"
    """
    The priority.
    """
    Conditions: List["RuleCondition"]
    """
    The conditions.

    Each rule can include zero or one of the following conditions: ``http-request-method``, ``host-header``,
    ``path-pattern``, and ``source-ip``, and zero or more of the following conditions: ``http-header`` and ``query-string``.
    """
    Actions: List["Action"]
    """
    The actions.

    Each rule must include exactly one of the following types of actions: ``forward``, ``redirect``, or
    ``fixed-response``, and it must be the last action to be performed.
    """
    IsDefault: bool | None = False
    """
    Indicates whether this is the default rule.
    """
    RuleArn: str | None = None
    """
    The Amazon Resource Name (ARN) of the rule.
    """

    @property
    def pk(self) -> str | None:
        """
        Return the primary key of the model.   This is the value of the
        :py:attr:`RuleArn` attribute.

        Returns:
            The primary key of the model instance.
        """
        return self.RuleArn

    @property
    def arn(self) -> str | None:
        """
        Return the ARN of the model.   This is the value of the :py:attr:`RuleArn`
        attribute.

        Returns:
            The ARN of the model instance.
        """
        return self.RuleArn

    def __hash__(self) -> int:
        """
        Return the hash of the model.

        This is the value of the
        :py:attr:`RuleArn` attribute.
        """
        return hash(self.RuleArn)


class ResponseCodeMatcher(Boto3Model):
    """
    The codes to use when checking for a successful response from a target.

    If the protocol version is gRPC, these are gRPC codes. Otherwise, these are HTTP
    codes.
    """

    HttpCode: str | None = None
    """
    For Application Load Balancers, you can specify values between 200 and 499, with the
    default value being 200.

    You can specify multiple values (for example, "200,202") or a range of values (for
    example, "200-299").
    """
    GrpcCode: str | None = None
    """
    You can specify values between 0 and 99.

    You can specify multiple values (for example, "0,1") or a range of values (for
    example, "0-5"). The default value is 12.
    """


class TargetDescription(Boto3Model):
    """
    Information about a target.
    """

    Id: str
    """
    The ID of the target.

    If the target type of the target group is ``instance``, specify an instance ID. If the target type
    is ``ip``, specify an IP address. If the target type is ``lambda``, specify the ARN of the Lambda function. If the
    target type is ``alb``, specify the ARN of the Application Load Balancer target.
    """
    Port: int | None = None
    """
    The port on which the target is listening.

    If the target group protocol is GENEVE, the supported port is 6081. If the
    target type is ``alb``, the targeted Application Load Balancer must have at least one listener whose port matches the
    target group port. This parameter is not used if the target is a Lambda function.
    """
    AvailabilityZone: str | None = None
    """
    An Availability Zone or ``all``.

    This determines whether the target receives traffic from the load balancer nodes in
    the specified Availability Zone or from all enabled Availability Zones for the load
    balancer.
    """


class TargetGroup(PrimaryBoto3Model):
    """
    Information about a target group.
    """

    manager_class: ClassVar[Type[Boto3ModelManager]] = TargetGroupManager

    TargetGroupName: str
    """
    The name of the target group.
    """
    Protocol: Literal["HTTP", "HTTPS", "TCP", "TLS", "UDP", "TCP_UDP", "GENEVE"] | None = "HTTPS"
    """
    The protocol to use for routing traffic to the targets.
    """
    Port: int
    """
    The port on which the targets are listening.

    This parameter is not used if the target is a Lambda function.
    """
    VpcId: str
    """
    The ID of the VPC for the targets.
    """
    TargetType: Literal["instance", "ip", "lambda", "alb"] | None = "ip"
    """
    The type of target that you must specify when registering targets with this target
    group.

    The possible values are
    ``instance`` (register targets by instance ID), ``ip`` (register targets by IP address), ``lambda`` (register a single
    Lambda function as a target), or ``alb`` (register a single Application Load Balancer as a target).
    """
    IpAddressType: Literal["ipv4", "ipv6"] | None = "ipv4"
    """
    The IP address type.

    The default value is ``ipv4``.
    """
    TargetGroupArn: str | None = None
    """
    The Amazon Resource Name (ARN) of the target group.
    """
    HealthCheckProtocol: Literal["HTTP", "HTTPS", "TCP", "TLS", "UDP", "TCP_UDP", "GENEVE"] | None = None
    """
    The protocol to use to connect with the target.

    The GENEVE, TLS, UDP, and TCP_UDP protocols are not supported for health checks.
    """
    HealthCheckPort: str | None = None
    """
    The port to use to connect with the target.
    """
    HealthCheckEnabled: bool | None = None
    """
    Indicates whether health checks are enabled.
    """
    HealthCheckIntervalSeconds: int | None = None
    """
    The approximate amount of time, in seconds, between health checks of an individual
    target.
    """
    HealthCheckTimeoutSeconds: int | None = None
    """
    The amount of time, in seconds, during which no response means a failed health
    check.
    """
    HealthyThresholdCount: int | None = None
    """
    The number of consecutive health checks successes required before considering an
    unhealthy target healthy.
    """
    UnhealthyThresholdCount: int | None = None
    """
    The number of consecutive health check failures required before considering the
    target unhealthy.
    """
    HealthCheckPath: str | None = None
    """
    The destination for health checks on the targets.
    """
    Matcher: ResponseCodeMatcher | None = None
    """
    The HTTP or gRPC codes to use when checking for a successful response from a target.
    """
    LoadBalancerArns: List[str] | None = None
    """
    The Amazon Resource Name (ARN) of the load balancer that routes traffic to this
    target group.

    You can use each target group with only one load balancer.
    """
    ProtocolVersion: str | None = None
    """
    [HTTP/HTTPS protocol] The protocol version.

    The possible values are ``GRPC``, ``HTTP1``, and ``HTTP2``.
    """

    @property
    def pk(self) -> str | None:
        """
        Return the primary key of the model.   This is the value of the
        :py:attr:`TargetGroupArn` attribute.

        Returns:
            The primary key of the model instance.
        """
        return self.TargetGroupArn

    @property
    def arn(self) -> str | None:
        """
        Return the ARN of the model.   This is the value of the
        :py:attr:`TargetGroupArn` attribute.

        Returns:
            The ARN of the model instance.
        """
        return self.TargetGroupArn

    @property
    def name(self) -> str | None:
        """
        Return the name of the model.   This is the value of the
        :py:attr:`TargetGroupName` attribute.

        Returns:
            The name of the model instance.
        """
        return self.TargetGroupName

    def __hash__(self) -> int:
        """
        Return the hash of the model.

        This is the value of the
        :py:attr:`TargetGroupArn` attribute.
        """
        return hash(self.TargetGroupArn)

    @cached_property
    def load_balancers(self) -> List["LoadBalancer"] | None:
        """
        Return the ARNs of :py:class:`LoadBalancer` objects that this target group
        belongs to, if any.

        .. note::

            The output of this property is cached on the model instance, so
            calling this multiple times will not result in multiple calls to the
            AWS API.   If you need a fresh copy of the data, you can re-get the
            model instance from the manager.
        """

        try:
            pk = OrderedDict(
                {
                    "LoadBalancerArns": self.LoadBalancerArns,
                }
            )
        except AttributeError:
            return []
        return LoadBalancer.objects.using(self.session).list(**pk)  # type: ignore[arg-type]

    @cached_property
    def vpc(self) -> Optional["Vpc"]:
        """
        Return the :py:class:`Vpc` object that this target group belongs to, if any.

        .. note::

            The output of this property is cached on the model instance, so
            calling this multiple times will not result in multiple calls to the
            AWS API.   If you need a fresh copy of the data, you can re-get the
            model instance from the manager.
        """

        try:
            pk = OrderedDict(
                {
                    "VpcId": self.VpcId,
                }
            )
        except AttributeError:
            return None
        return Vpc.objects.using(self.session).get(**pk)  # type: ignore[arg-type]

    def targets(self) -> List["TargetHealthDescription"] | None:
        """
        Return the targets for the target group.
        """

        return (
            cast("TargetGroupManager", self.objects)  # type: ignore[attr-defined]
            .using(self.session)
            .targets(
                cast("str", self.arn),
            )
        )


# =======================
# Request/Response Models
# =======================


class SubnetMapping(Boto3Model):
    """
    Information about a subnet mapping.
    """

    SubnetId: str
    """
    The ID of the subnet.
    """
    AllocationId: str | None = None
    """
    [Network Load Balancers] The allocation ID of the Elastic IP address for an
    internet-facing load balancer.
    """
    PrivateIPv4Address: str | None = None
    """
    [Network Load Balancers] The private IPv4 address for an internal load balancer.
    """
    IPv6Address: str | None = None
    """
    [Network Load Balancers] The IPv6 address.
    """
    SourceNatIpv6Prefix: str | None = None
    """
    [Network Load Balancers with UDP listeners] The IPv6 prefix to use for source NAT.

    Specify an IPv6 prefix (/80 netmask)
    from the subnet CIDR block or ``auto_assigned`` to use an IPv6 prefix selected at random from the subnet CIDR block.
    """


class CreateLoadBalancerOutput(Boto3Model):
    LoadBalancers: List["LoadBalancer"] | None = None
    """
    Information about the load balancer.
    """


class DeleteLoadBalancerOutput(Boto3Model):
    pass


class DescribeLoadBalancersOutput(Boto3Model):
    LoadBalancers: List["LoadBalancer"] | None = None
    """
    Information about the load balancers.
    """
    NextMarker: str | None = None
    """
    If there are additional results, this is the marker for the next set of results.

    Otherwise, this is null.
    """


class LoadBalancerAttribute(Boto3Model):
    """
    Information about a load balancer attribute.
    """

    Key: str | None = None
    """
    The name of the attribute.
    """
    Value: str | None = None
    """
    The value of the attribute.
    """


class DescribeLoadBalancerAttributesOutput(Boto3Model):
    Attributes: List["LoadBalancerAttribute"] | None = None
    """
    Information about the load balancer attributes.
    """


class CreateListenerOutput(Boto3Model):
    Listeners: List["Listener"] | None = None
    """
    Information about the listener.
    """


class ModifyListenerOutput(Boto3Model):
    Listeners: List["Listener"] | None = None
    """
    Information about the modified listener.
    """


class DeleteListenerOutput(Boto3Model):
    pass


class DescribeListenersOutput(Boto3Model):
    Listeners: List["Listener"] | None = None
    """
    Information about the listeners.
    """
    NextMarker: str | None = None
    """
    If there are additional results, this is the marker for the next set of results.

    Otherwise, this is null.
    """


class CreateRuleOutput(Boto3Model):
    Rules: List["Rule"] | None = None
    """
    Information about the rule.
    """


class ModifyRuleOutput(Boto3Model):
    Rules: List["Rule"] | None = None
    """
    Information about the modified rule.
    """


class DeleteRuleOutput(Boto3Model):
    pass


class DescribeRulesOutput(Boto3Model):
    Rules: List["Rule"] | None = None
    """
    Information about the rules.
    """
    NextMarker: str | None = None
    """
    If there are additional results, this is the marker for the next set of results.

    Otherwise, this is null.
    """


class CreateTargetGroupOutput(Boto3Model):
    TargetGroups: List["TargetGroup"] | None = None
    """
    Information about the target group.
    """


class ModifyTargetGroupOutput(Boto3Model):
    TargetGroups: List["TargetGroup"] | None = None
    """
    Information about the modified target group.
    """


class DeleteTargetGroupOutput(Boto3Model):
    pass


class DescribeTargetGroupsOutput(Boto3Model):
    TargetGroups: List["TargetGroup"] | None = None
    """
    Information about the target groups.
    """
    NextMarker: str | None = None
    """
    If there are additional results, this is the marker for the next set of results.

    Otherwise, this is null.
    """


class TargetHealthInfo(Boto3Model):
    """
    Information about the current health of a target.
    """

    State: Literal["initial", "healthy", "unhealthy", "unhealthy.draining", "unused", "draining", "unavailable"] | None = None
    """
    The state of the target.
    """
    Reason: Literal["Elb.RegistrationInProgress", "Elb.InitialHealthChecking", "Target.ResponseCodeMismatch", "Target.Timeout", "Target.FailedHealthChecks", "Target.NotRegistered", "Target.NotInUse", "Target.DeregistrationInProgress", "Target.InvalidState", "Target.IpUnusable", "Target.HealthCheckDisabled", "Elb.InternalError"] | None = None
    """
    The reason code.
    """
    Description: str | None = None
    """
    A description of the target health that provides additional details.

    If the state is ``healthy``, a description is not
    provided.
    """


class AnomalyDetectionInfo(Boto3Model):
    """
    Information about anomaly detection and mitigation.
    """

    Result: Literal["anomalous", "normal"] | None = None
    """
    The latest anomaly detection result.
    """
    MitigationInEffect: Literal["yes", "no"] | None = None
    """
    Indicates whether anomaly mitigation is in progress.
    """


class ElbV2AdministrativeOverride(Boto3Model):
    """
    Information about the override status applied to a target.
    """

    State: Literal["unknown", "no_override", "zonal_shift_active", "zonal_shift_delegated_to_dns"] | None = None
    """
    The state of the override.
    """
    Reason: Literal["AdministrativeOverride.Unknown", "AdministrativeOverride.NoOverride", "AdministrativeOverride.ZonalShiftActive", "AdministrativeOverride.ZonalShiftDelegatedToDns"] | None = None
    """
    The reason code for the state.
    """
    Description: str | None = None
    """
    A description of the override state that provides additional details.
    """


class TargetHealthDescription(Boto3Model):
    """
    Information about the health of a target.
    """

    Target: TargetDescription | None = None
    """
    The description of the target.
    """
    HealthCheckPort: str | None = None
    """
    The port to use to connect with the target.
    """
    TargetHealth: TargetHealthInfo | None = None
    """
    The health information for the target.
    """
    AnomalyDetection: AnomalyDetectionInfo | None = None
    """
    The anomaly detection result for the target.
    """
    AdministrativeOverride: ElbV2AdministrativeOverride | None = None
    """
    The administrative override information for the target.
    """


class DescribeTargetHealthOutput(Boto3Model):
    TargetHealthDescriptions: List["TargetHealthDescription"] | None = None
    """
    Information about the health of the targets.
    """
