"""
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.disassociate_route_table
hub.tool.boto3.resource.exec(resource, associate_with_subnet, *args, **kwargs)
"""
import copy
from typing import Any
from typing import Dict

__contracts__ = ["resource"]


async def present(
    hub,
    ctx,
    name: str,
    route_table_id: str,
    resource_id: str = None,
    subnet_id: str = None,
    gateway_id: str = None,
) -> Dict[str, Any]:
    r"""
    **Autogenerated function**

    Associates a subnet in your VPC or an internet gateway or virtual private gateway attached to your VPC with a
    route table in your VPC. This association causes traffic from the subnet or gateway to be routed according to the
    routes in the route table. The action returns an association ID, which you need in order to disassociate the
    route table later. A route table can be associated with multiple subnets.

    Args:
        name(Text): An Idem name to identify the route table resource.
        resource_id(Text, optional): AWS Route Table ID.
        route_table_id(Text): The ID of the route table.
        subnet_id(Text, optional): The ID of the subnet. A subnet ID is not returned for an implicit association.
        gateway_id(Text, optional): The ID of the internet gateway or virtual private gateway.

    Request Syntax:
        [route_table-resource-name]:
          aws.ec2.route_table_association.present:
          - route_table_id: 'string'
          - resource_id: 'string'
          - subnet_id: 'string'
          - gateway_id: 'string'

    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: sls

            test_route-table_association:
              aws.ec2.route_table_association.present:
              - route_table_id: vpc-02850adfa9f6fc916
              - resource_id: route_table-3485hydfe5f6tb998
              - gateway_id: vgw-0334141b528f99316
              - subnet_id: subnet-0610f7c1a12a1af6a
    """

    result = dict(comment=(), old_state=None, new_state=None, name=name, result=True)
    before = await hub.exec.boto3.client.ec2.describe_route_tables(
        ctx, RouteTableIds=[route_table_id]
    )
    if before and before["result"]:
        route_table_resource = before["ret"].get("RouteTables")[0]
        if resource_id:
            ret = hub.tool.aws.ec2.route_table.get_route_table_association_by_id(
                route_table_resource["Associations"], resource_id=resource_id
            )
            if ret["result"]:
                result[
                    "old_state"
                ] = hub.tool.aws.ec2.conversion_utils.convert_raw_route_table_association_to_present(
                    resource=ret["ret"],
                    idem_resource_name=name,
                )
                result["comment"] = (
                    f"aws.ec2.route_table_association '{name}' association already exists",
                )
                result["new_state"] = copy.deepcopy(result["old_state"])
                return result

        if ctx.get("test", False):
            result["new_state"] = hub.tool.aws.test_state_utils.generate_test_state(
                enforced_state={},
                desired_state={
                    "name": name,
                    "route_table_id": route_table_id,
                    "resource_id": name,
                    "subnet_id": subnet_id,
                    "gateway_id": gateway_id,
                },
            )
            result["comment"] = hub.tool.aws.comment_utils.would_create_comment(
                resource_type="aws.ec2.route_table_association", name=name
            )
            return result
        ret = await hub.exec.boto3.client.ec2.associate_route_table(
            ctx, RouteTableId=route_table_id, SubnetId=subnet_id, GatewayId=gateway_id
        )
        if not ret["result"]:
            result["result"] = False
            result["comment"] = ret["comment"]
            return result
        result["comment"] = hub.tool.aws.comment_utils.create_comment(
            resource_type="aws.ec2.route_table_association", name=name
        )
    try:
        after = await hub.exec.boto3.client.ec2.describe_route_tables(
            ctx, RouteTableIds=[route_table_id]
        )
        resource = after["ret"].get("RouteTables")[0]
        association = hub.tool.aws.ec2.route_table.get_route_table_association_by_id(
            resource["Associations"], gateway_id=gateway_id, subnet_id=subnet_id
        )
        result[
            "new_state"
        ] = hub.tool.aws.ec2.conversion_utils.convert_raw_route_table_association_to_present(
            resource=association["ret"],
            idem_resource_name=name,
        )
    except Exception as e:
        result["comment"] = result["comment"] + (str(e),)
        result["result"] = False
    return result


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

    Disassociates a subnet or gateway from a route table. After you perform this action, the subnet no longer uses
    the routes in the route table. Instead, it uses the routes in the VPC's main route table.

    Args:
        name(Text): An Idem name to identify the route table resource.
        route_table_id(Text): The ID of the route table.
        resource_id(Text, optional): AWS Route Table ID. Idem automatically considers this resource being absent
         if this field is not specified.

    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: sls

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

    result = dict(comment=(), old_state=None, new_state=None, name=name, result=True)
    if not resource_id:
        result["comment"] = hub.tool.aws.comment_utils.already_absent_comment(
            resource_type="aws.ec2.route_table_association", name=name
        )
        return result
    before = await hub.exec.boto3.client.ec2.describe_route_tables(
        ctx, RouteTableIds=[route_table_id]
    )
    if not before["result"]:
        result["comment"] = hub.tool.aws.comment_utils.already_absent_comment(
            resource_type="aws.ec2.route_table_association", name=name
        )
    else:
        if before["ret"] and before["ret"]["RouteTables"]:
            resource = before["ret"]["RouteTables"][0]
            association_ret = (
                hub.tool.aws.ec2.route_table.get_route_table_association_by_id(
                    resource["Associations"], resource_id=resource_id
                )
            )
            if association_ret["result"]:
                result[
                    "old_state"
                ] = hub.tool.aws.ec2.conversion_utils.convert_raw_route_table_association_to_present(
                    resource=association_ret["ret"],
                    idem_resource_name=name,
                )
                if ctx.get("test", False):
                    result["comment"] = hub.tool.aws.comment_utils.would_delete_comment(
                        resource_type="aws.ec2.route_table_association", name=name
                    )
                    return result
                ret = await hub.exec.boto3.client.ec2.disassociate_route_table(
                    ctx, AssociationId=resource_id
                )
                if not ret.get("result"):
                    result["comment"] = result["comment"] + ret["comment"]
                    result["result"] = False
                    return result
                result["comment"] = hub.tool.aws.comment_utils.delete_comment(
                    resource_type="aws.ec2.route_table_association", name=name
                )
            else:
                result["comment"] = hub.tool.aws.comment_utils.already_absent_comment(
                    resource_type="aws.ec2.route_table_association", name=name
                )
                return result
    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 table associations. 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_association
    """

    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"]:
        if route_table["Associations"]:
            for association in route_table["Associations"]:
                if association["AssociationState"]["State"] == "associated":
                    route_table_association_id = association["RouteTableAssociationId"]
                    resource_converted = hub.tool.aws.ec2.conversion_utils.convert_raw_route_table_association_to_present(
                        resource=association,
                        idem_resource_name=route_table_association_id,
                    )
                    result[route_table_association_id] = {
                        "aws.ec2.route_table_association.present": [
                            {parameter_key: parameter_value}
                            for parameter_key, parameter_value in resource_converted.items()
                        ]
                    }
    return result
