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

hub.exec.boto3.client.ec2.associate_route_table
hub.exec.boto3.client.ec2.create_route_table
hub.exec.boto3.client.ec2.delete_route_table
hub.exec.boto3.client.ec2.describe_route_tables
hub.exec.boto3.client.ec2.disassociate_route_table
resource = hub.tool.boto3.resource.create(ctx, "ec2", "RouteTable", name)
hub.tool.boto3.resource.exec(resource, associate_with_subnet, *args, **kwargs)
hub.tool.boto3.resource.exec(resource, create_route, *args, **kwargs)
hub.tool.boto3.resource.exec(resource, create_tags, *args, **kwargs)
hub.tool.boto3.resource.exec(resource, delete, *args, **kwargs)
"""
from collections import OrderedDict
from typing import Any
from typing import Dict
from typing import List

__contracts__ = ["resource"]

TREQ = {
    "present": {
        "require": [
            "aws.ec2.vpc.present",
        ],
    },
}


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

    Creates a route table for the specified VPC. After you create a route table, you can add routes and associate
    the table with a subnet. For more information, see Route tables in the Amazon Virtual Private Cloud User Guide.

    Args:
        tags(List, optional): The tags to assign to the route_table. 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.
        vpc_id(Text): ID of the VPC.
        name(Text): A name, ID, or JMES search path to identify the resource.

    Request Syntax:
        [route_table-resource-id]:
          aws.ec2.route_table.present:
          - vpc_id: 'string'
          - tags:
            - Key: 'string'
              Value: 'string'

    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: sls

            resource_is_present:
              aws.ec2.route_table.present:
                - name: value
    """

    result = dict(comment="", old_state=None, new_state=None, name=name, result=True)
    created_route_table_id = name
    update_tags = False
    before = await hub.exec.boto3.client.ec2.describe_route_tables(
        ctx, DryRun=False, RouteTableIds=[name]
    )

    if before and before["result"] and before["ret"].get("RouteTables"):
        route_table_resource = before["ret"].get("RouteTables")[0]
        if tags is not None:
            # Update tags
            update_ret = await hub.exec.aws.ec2.tag.update_tags(
                ctx=ctx,
                resource_id=route_table_resource.get("RouteTableId"),
                old_tags=route_table_resource.get("Tags"),
                new_tags=tags,
            )
            update_tags = True
            result["comment"] = f"'{name}' already present. Updating tags"
            if not update_ret["result"]:
                result["comment"] = update_ret["comment"]
                result["result"] = False
    else:
        try:
            ret = await hub.exec.boto3.client.ec2.create_route_table(
                ctx,
                DryRun=False,
                TagSpecifications=[{"ResourceType": "transit-gateway", "Tags": tags}]
                if tags
                else None,
                VpcId=vpc_id,
            )
            result["result"] = ret["ret"]
            if not result["result"]:
                result["comment"] = ret["comment"]
                return result
            created_route_table_id = ret["ret"]["RouteTable"]["RouteTableId"]
            ret["comment"] = f"Created '{created_route_table_id}'"
        except hub.tool.boto3.exception.ClientError as e:
            result["comment"] = f"{e.__class__.__name__}: {e}"
            result["result"] = False

    after = None
    if update_tags or created_route_table_id is not None:
        after = await hub.exec.boto3.client.ec2.describe_route_tables(
            ctx, DryRun=False, RouteTableIds=[created_route_table_id]
        )
    if before["result"] and before["ret"].get("RouteTables"):
        result["old_state"] = before["ret"]["RouteTables"][0]
    if after and after["result"] and after["ret"].get("RouteTables"):
        result["new_state"] = after["ret"]["RouteTables"][0]
    return result


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

    Deletes the specified route table. You must disassociate the route table from any subnets before you can delete
    it. You can't delete the main route table.

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

    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: sls

            resource_is_absent:
              aws.ec2.route_table.absent:
                - name: value
    """

    result = dict(comment="", old_state=None, new_state=None, name=name, result=True)
    route_table_id_list = [name]
    before = await hub.exec.boto3.client.ec2.describe_route_tables(
        ctx, DryRun=False, RouteTableIds=route_table_id_list
    )
    if before and not before["result"]:
        result["comment"] = before["comment"]
        result["result"] = False
        return result

    if before["result"] and before["ret"].get("RouteTables"):
        result["old_state"] = before["ret"]["RouteTables"][0]

    if not before:
        result["comment"] = f"'{name}' already absent"
    elif ctx.get("test", False):
        result["comment"] = f"Would delete aws.ec2.route_table {name}"
        return result
    else:
        try:
            ret = await hub.exec.boto3.client.ec2.delete_route_table(
                ctx, RouteTableId=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 of your route tables. Each subnet in your VPC must be associated with a route table. If a
    subnet is not explicitly associated with any route table, it is implicitly associated with the main route table.
    This command does not return the subnet ID for implicit associations. For more information, see Route tables in
    the Amazon Virtual Private Cloud User Guide.


    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: bash

            $ idem describe aws.ec2.route_table
    """

    result = {}

    ret = await hub.exec.boto3.client.ec2.describe_route_tables(ctx)
    if not ret["result"]:
        hub.log.debug(f"Could not describe route_table {ret['comment']}")
        return result

    for route_table in ret["ret"]["RouteTables"]:
        route_table_id = route_table.get("RouteTableId")
        describe_parameters = OrderedDict(
            {
                "VpcId": "vpc_id",
                "Tags": "tags",
            }
        )
        new_route_table = []
        for parameter_old_key, parameter_new_key in describe_parameters.items():
            if route_table.get(parameter_old_key) is not None:
                new_route_table.append(
                    {parameter_new_key: route_table.get(parameter_old_key)}
                )

        result[route_table_id] = {"aws.ec2.route_table.present": new_route_table}
    return result
