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

hub.exec.boto3.client.ec2.create_transit_gateway
hub.exec.boto3.client.ec2.delete_transit_gateway
hub.exec.boto3.client.ec2.describe_transit_gateways
hub.exec.boto3.client.ec2.modify_transit_gateway
"""
from collections import OrderedDict
from typing import Any
from typing import Dict
from typing import List

__contracts__ = ["resource"]


async def present(
    hub,
    ctx,
    name: str,
    description: str = None,
    options: dict = None,
    tags: List = None,
) -> Dict[str, Any]:
    r"""
    **Autogenerated function**

    Creates a transit gateway. You can use a transit gateway to interconnect your virtual private clouds (VPC) and
    on-premises networks. After the transit gateway enters the available state, you can attach your VPCs and VPN
    connections to the transit gateway. To attach your VPCs, use CreateTransitGatewayVpcAttachment. To attach a VPN
    connection, use CreateCustomerGateway to create a customer gateway and specify the ID of the customer gateway
    and the ID of the transit gateway in a call to CreateVpnConnection. When you create a transit gateway, we create
    a default transit gateway route table and use it as the default association route table and the default
    propagation route table. You can use CreateTransitGatewayRouteTable to create additional transit gateway route
    tables. If you disable automatic route propagation, we do not create a default transit gateway route table. You
    can use EnableTransitGatewayRouteTablePropagation to propagate routes from a resource attachment to a transit
    gateway route table. If you disable automatic associations, you can use AssociateTransitGatewayRouteTable to
    associate a resource attachment with a transit gateway route table.

    Args:
        name(Text): A name, ID to identify the resource.
        description(str, Optional): description for the transit gateway to identify the resource
        options(dictionary, optional): Options about transit gateway
             *  AmazonSideAsn (int) -- A private Autonomous System Number (ASN) for the Amazon side of a BGP session.
                                       The range is 64512 to 65534 for 16-bit ASNs and 4200000000 to 4294967294 for 32-bit ASNs.
                                       The default is 64512 .
             *  AutoAcceptSharedAttachments (string) -- 'Enable or disable automatic acceptance of attachment requests. Disabled by default.
             *  DefaultRouteTableAssociation (string) -- Enable or disable automatic association with the default association route table. Enabled by default.,
             *  DefaultRouteTablePropagation (string) -- Enable or disable automatic propagation of routes to the default propagation route table. Enabled by default.,
             *  VpnEcmpSupport (string) -- Enable or disable Equal Cost Multipath Protocol support. Enabled by default.,
             *  DnsSupport (string) -- Enable or disable DNS support. Enabled by default.,
             *  MulticastSupport (string) -- Indicates whether multicast is enabled on the transit gateway,
             *  TransitGatewayCidrBlocks (list) -- One or more IPv4 or IPv6 CIDR blocks for the transit gateway. Must be a size /24 CIDR block or larger for IPv4, or a size /64 CIDR block or larger for IPv6.

        tags(List, optional): The tags to assign to the Transit gateway. Defaults to None.
            * Key (string) -- The key of the tag. Tag keys are case-sensitive and accept a maximum of 127 Unicode characters. May not begin with aws: .
            * Value (string) -- The value of the tag. Tag values are case-sensitive and accept a maximum of 255 Unicode characters.

    Request Syntax:
        [transit-gateway-resource-id]:
          aws.ec2.transit_gateway.present:
            - description: 'string'
            - options:
                AmazonSideAsn: int
                AutoAcceptSharedAttachments: 'string'
                DefaultRouteTableAssociation: 'string'
                DefaultRouteTablePropagation: 'string'
                VpnEcmpSupport: 'string'
                DnsSupport: 'string'
                MulticastSupport: 'string'
                TransitGatewayCidrBlocks:
                  - 'string'
                  - 'string'
            - tags:
              - Key: 'string'
                Value: 'string'
    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: sls

            tgw-02994a8dda824c337:
                  aws.ec2.transit_gateway.present:
                  - description: test transit gateway
                  - options:
                      AmazonSideAsn: 64512
                      AutoAcceptSharedAttachments: enable
                      DefaultRouteTableAssociation: enable
                      DefaultRouteTablePropagation: enable
                      DnsSupport: enable
                      MulticastSupport: disable
                      TransitGatewayCidrBlocks:
                      - 10.0.0.0/24
                      - 198.0.0.0/16
                      VpnEcmpSupport: enable
                  - tags:
                    - Key: BU
                      Value: vRA-CS-GR
                    - Key: Organization
                      Value: vmw
                    - Key: Name
                      Value: transit-gateway-2

    """
    result = dict(comment="", old_state=None, new_state=None, name=name, result=True)
    before = await hub.exec.aws.ec2.transit_gateway.get_transit_gateway_by_id(ctx, name)
    before = before["ret"]
    result["old_state"] = before
    if ctx.get("test", False):
        if before:
            result["comment"] = f"Would update aws.ec2.transit_gateway {name}"
            result["result"] = True
        else:
            result["comment"] = f"Would create aws.ec2.transit_gateway {name}"
            result["result"] = True
        return result

    try:
        if before:
            update_ret = await hub.exec.aws.ec2.transit_gateway.update_options(
                ctx=ctx,
                transit_gateway_id=before.get("TransitGatewayId"),
                old_description=before.get("Description"),
                new_description=description,
                old_options=before.get("Options"),
                new_options=options,
            )
            if not update_ret["result"]:
                result["comment"] = update_ret["comment"]
                result["result"] = False
            if result["result"] and (tags is not None):
                # Update tags
                update_ret = await hub.exec.aws.ec2.tag.update_tags(
                    ctx=ctx,
                    resource_id=before.get("TransitGatewayId"),
                    old_tags=before.get("Tags"),
                    new_tags=tags,
                )
                if not update_ret["result"]:
                    result["comment"] = update_ret["comment"]
                    result["result"] = False

            if result["result"]:
                result["comment"] = f"'Updated transit gateway {name}'"

        else:
            ret = await hub.exec.boto3.client.ec2.create_transit_gateway(
                ctx,
                Description=description,
                Options=options,
                TagSpecifications=[{"ResourceType": "transit-gateway", "Tags": tags}]
                if tags
                else None,
            )
            result["comment"] = f"Created '{name}'"
            result["result"] = ret["result"]

            if ret["result"] and ret["ret"] and "TransitGateway" in ret["ret"]:
                name = ret["ret"]["TransitGateway"]["TransitGatewayId"]

            if not result["result"]:
                result["comment"] = ret["comment"]
                return result

    except hub.tool.boto3.exception.ClientError as e:
        result["result"] = False
        result["comment"] = f"{e.__class__.__name__}: {e}"

    try:
        after = await hub.exec.aws.ec2.transit_gateway.get_transit_gateway_by_id(
            ctx, name
        )
        after = after["ret"]
        result["new_state"] = after
    except Exception as e:
        result["comment"] = str(e)
        result["result"] = False
    return result


async def absent(hub, ctx, name: str) -> Dict[str, Any]:
    r"""
    **Autogenerated function**

    Deletes the specified transit gateway.

    Args:
        name(Text): A name, ID to identify the resource.

    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: sls

            tgw-02994a8dda824c337:
              aws.ec2.transit_gateway.absent:
                - name: value
    """

    result = dict(comment="", old_state=None, new_state=None, name=name, result=True)
    before = await hub.exec.aws.ec2.transit_gateway.get_transit_gateway_by_id(ctx, name)
    if not before["result"]:
        result["comment"] = before["comment"]
        result["result"] = False
        return result
    before = before["ret"]
    result["old_state"] = before
    if not before:
        result["comment"] = f"'{name}' already absent"
    elif before["State"] and (
        before["State"] == "deleted" or before["State"] == "deleting"
    ):
        result["comment"] = f"'{name}' is already {before['State']}"
    elif ctx.get("test", False):
        result["comment"] = f"Would delete aws.ec2.transit_gateway {name}"
        return result
    else:
        try:
            ret = await hub.exec.boto3.client.ec2.delete_transit_gateway(
                ctx, TransitGatewayId=name
            )
            result["result"] = ret["result"]
            if not result["result"]:
                result["comment"] = ret["comment"]
                result["result"] = False
                return result
            result["comment"] = f"Deleted '{name}'"
        except hub.tool.boto3.exception.ClientError as e:
            result["comment"] = f"{e.__class__.__name__}: {e}"
    return result


async def describe(hub, ctx) -> Dict[str, Dict[str, Any]]:
    r"""
    **Autogenerated function**

    Describe the resource in a way that can be recreated/managed with the corresponding "present" function


    Describes one or more transit gateways. By default, all transit gateways are described. Alternatively, you can
    filter the results.


    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: bash

            $ idem describe aws.ec2.transit_gateway
    """

    result = {}

    ret = await hub.exec.boto3.client.ec2.describe_transit_gateways(ctx)
    if not ret["result"]:
        hub.log.debug(f"Could not describe transit_gateway {ret['comment']}")
        return result
    describe_parameters = OrderedDict(
        {
            "Description": "description",
            "State": "state",
            "Options": "options",
            "TransitGatewayArn": "transit_gateway_arn",
            "OwnerId": "owner_id",
            "Tags": "tags",
        }
    )
    for transit_gateway in ret["ret"]["TransitGateways"]:
        transit_gateway_id = transit_gateway.get("TransitGatewayId")
        resource_translated = []

        for parameter_old_key, parameter_new_key in describe_parameters.items():
            if transit_gateway.get(parameter_old_key) is not None:
                resource_translated.append(
                    {parameter_new_key: transit_gateway.get(parameter_old_key)}
                )

        result[transit_gateway_id] = {
            "aws.ec2.transit_gateway.present": resource_translated
        }

    return result
