"""
Autogenerated state module using `pop-create-idem <https://gitlab.com/saltstack/pop/pop-create-idem>`__

hub.exec.boto3.client.ec2.allocate_address
hub.exec.boto3.client.ec2.associate_address
hub.exec.boto3.client.ec2.describe_addresses
hub.exec.boto3.client.ec2.disassociate_address
hub.exec.boto3.client.ec2.release_address
"""



from typing import *
import dict_tools.differ as differ
async def present(hub, ctx, name: Text, allocation_id: Text = None, instance_id: Text = None, public_ip: Text = None, allow_reassociation: bool = None, network_interface_id: Text = None, private_ip_address: Text = None)  -> Dict[str, Any]:
    r'''
    **Autogenerated function**
    
    Associates an Elastic IP address, or carrier IP address (for instances that are in subnets in Wavelength Zones)
    with an instance or a network interface. Before you can use an Elastic IP address, you must allocate it to your
    account. An Elastic IP address is for use in either the EC2-Classic platform or in a VPC. For more information,
    see Elastic IP Addresses in the Amazon Elastic Compute Cloud User Guide. [EC2-Classic, VPC in an EC2-VPC-only
    account] If the Elastic IP address is already associated with a different instance, it is disassociated from
    that instance and associated with the specified instance. If you associate an Elastic IP address with an
    instance that has an existing Elastic IP address, the existing address is disassociated from the instance, but
    remains allocated to your account. [VPC in an EC2-Classic account] If you don't specify a private IP address,
    the Elastic IP address is associated with the primary IP address. If the Elastic IP address is already
    associated with a different instance or a network interface, you get an error unless you allow reassociation.
    You cannot associate an Elastic IP address with an instance or network interface that has an existing Elastic IP
    address. [Subnets in Wavelength Zones] You can associate an IP address from the telecommunication carrier to the
    instance or network interface.  You cannot associate an Elastic IP address with an interface in a different
    network border group.  This is an idempotent operation. If you perform the operation more than once, Amazon EC2
    doesn't return an error, and you may be charged for each time the Elastic IP address is remapped to the same
    instance. For more information, see the Elastic IP Addresses section of Amazon EC2 Pricing.

    Args:
        name(Text): The name of the state.
        allocation_id(Text, optional): [EC2-VPC] The allocation ID. This is required for EC2-VPC. Defaults to None.
        instance_id(Text, optional): The ID of the instance. The instance must have exactly one attached network interface. For
            EC2-VPC, you can specify either the instance ID or the network interface ID, but not both. For
            EC2-Classic, you must specify an instance ID and the instance must be in the running state. Defaults to None.
        public_ip(Text, optional): [EC2-Classic] The Elastic IP address to associate with the instance. This is required for
            EC2-Classic. Defaults to None.
        allow_reassociation(bool, optional): [EC2-VPC] For a VPC in an EC2-Classic account, specify true to allow an Elastic IP address that
            is already associated with an instance or network interface to be reassociated with the
            specified instance or network interface. Otherwise, the operation fails. In a VPC in an EC2-VPC-
            only account, reassociation is automatic, therefore you can specify false to ensure the
            operation fails if the Elastic IP address is already associated with another resource. Defaults to None.
        network_interface_id(Text, optional): [EC2-VPC] The ID of the network interface. If the instance has more than one network interface,
            you must specify a network interface ID. For EC2-VPC, you can specify either the instance ID or
            the network interface ID, but not both. Defaults to None.
        private_ip_address(Text, optional): [EC2-VPC] The primary or secondary private IP address to associate with the Elastic IP address.
            If no private IP address is specified, the Elastic IP address is associated with the primary
            private IP address. Defaults to None.

    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: sls

            resource_is_present:
              aws_auto.ec2.address.present:
                - name: value
    '''
    
    result = dict(comment="", changes= None, name=name, result=True)

    
    before = await hub.exec.boto3.client.ec2.describe_addresses(name)

    if before:
        result["comment"] = f"'{name}' already exists"
    else:
        try:
            ret = await hub.exec.boto3.client.ec2.associate_address(
                ctx,
                DryRun=ctx.test,
                
                **{"AllocationId": allocation_id, "InstanceId": instance_id, "PublicIp": public_ip, "AllowReassociation": allow_reassociation, "NetworkInterfaceId": network_interface_id, "PrivateIpAddress": private_ip_address}
            )
            result["result"] = ret["status"]
            if not result["result"]:
                result["comment"] = ret["comment"]
                return result
            ret["comment"] = f"Created '{name}'"
        except hub.tool.boto3.exception.ClientError as e:
            result["comment"] = f"{e.__class__.__name__}: {e}"

    
    # TODO perform other modifications as needed here
    ...

    after = await hub.exec.boto3.client.ec2.describe_addresses(name)
    result["changes"] = differ.deep_diff(before, after)
    return result

async def absent(hub, ctx, name: Text, association_id: Text = None, public_ip: Text = None)  -> Dict[str, Any]:
    r'''
    **Autogenerated function**
    
    Disassociates an Elastic IP address from the instance or network interface it's associated with. An Elastic IP
    address is for use in either the EC2-Classic platform or in a VPC. For more information, see Elastic IP
    Addresses in the Amazon Elastic Compute Cloud User Guide. This is an idempotent operation. If you perform the
    operation more than once, Amazon EC2 doesn't return an error.

    Args:
        name(Text): The name of the state.
        association_id(Text, optional): [EC2-VPC] The association ID. Required for EC2-VPC. Defaults to None.
        public_ip(Text, optional): [EC2-Classic] The Elastic IP address. Required for EC2-Classic. Defaults to None.

    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: sls

            resource_is_absent:
              aws_auto.ec2.address.absent:
                - name: value
    '''
    
    result = dict(comment="", changes= None, name=name, result=True)

    

    before = await hub.exec.boto3.client.ec2.describe_addresses(name)

    if not before:
        result["comment"] = f"'{name}' already absent"
    else:
        try:
            ret = await hub.exec.boto3.client.ec2.disassociate_address(
                ctx,
                DryRun=ctx.test,
                
                **{"AssociationId": association_id, "PublicIp": public_ip}
            )
            result["result"] = ret["status"]
            if not result["result"]:
                result["comment"] = ret["comment"]
                return result
            result["comment"] = f"Deleted '{name}'"
        except hub.tool.boto3.exception.ClientError as e:
            result["comment"] = f"{e.__class__.__name__}: {e}"

    

    after = await hub.exec.boto3.client.ec2.describe_addresses(name)
    result["changes"] = differ.deep_diff(before, after)
    return result

