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

hub.exec.boto3.client.ec2.attach_internet_gateway
hub.exec.boto3.client.ec2.create_internet_gateway
hub.exec.boto3.client.ec2.delete_internet_gateway
hub.exec.boto3.client.ec2.describe_internet_gateways
hub.exec.boto3.client.ec2.detach_internet_gateway
resource = hub.tool.boto3.resource.create(ctx, "ec2", "InternetGateway", name)
hub.tool.boto3.resource.exec(resource, attach_to_vpc, *args, **kwargs)
hub.tool.boto3.resource.exec(resource, create_tags, *args, **kwargs)
"""
from typing import Any
from typing import Dict
from typing import List

__contracts__ = ["resource"]


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

    Creates an internet gateway for use with a VPC. After creating the internet gateway, you attach it to a VPC
    using AttachInternetGateway. For more information about your VPC and internet gateway, see the Amazon Virtual
    Private Cloud User Guide.

    Args:
        name(Text): The ID of the internet gateway.
        tags(List, optional): The tags to apply to the resource.
            * 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(List, optional): This list can contain only single element. This is ID of VPC to which internet gateway attaches.
        If vpc_id is not passed, then attach/detach operation is ignored.
        If user passes empty list, then attached vpc is detached.

    Request Syntax:
        [internet_gateway-id]:
          aws.ec2.internet_gateway.present:
          - vpc_id:
            - 'string'
          - tags:
            - Key: 'string'
              Value: 'string'
    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: sls

            igw-54c83a2c:
             aws.ec2.internet_gateway.present:
             - vpc_id:
               - vpc-d04fbf46
             - tags:
               - Key: Name
                 Value: igw-54c83a2c
    """

    result = dict(comment="", old_state=None, new_state=None, name=name, result=True)
    resource = hub.tool.boto3.resource.create(ctx, "ec2", "InternetGateway", name)
    # Skip fetching resource if there is no change
    update_new_state = True
    before = await hub.tool.boto3.resource.describe(resource)
    if ctx.get("test", False):
        if before:
            result["comment"] = f"Would update aws.ec2.internet_gateway {name}"
            result["result"] = True
        else:
            result["comment"] = f"Would create aws.ec2.internet_gateway {name}"
            result["result"] = True
        return result

    if before:
        result["old_state"] = before
        result["comment"] = f"'{name}' already exists"
        try:
            if tags is not None:
                update_ret = await hub.exec.aws.ec2.tag.update_tags(
                    ctx=ctx,
                    resource_id=name,
                    old_tags=before.get("Tags", None),
                    new_tags=tags,
                )
                if not update_ret["result"]:
                    result["comment"] = update_ret["comment"]
                    result["result"] = False
                    return result
                else:
                    result["comment"] = f"Updated tags '{tags}'"

            ret = await hub.exec.aws.ec2.internet_gateway.update_attachments(
                ctx=ctx,
                internet_gateway_name=name,
                vpc_id=vpc_id,
                before=before,
            )
            result["result"] = ret["result"]
            result["comment"] = ret["comment"]
            if tags is None and vpc_id is None:
                update_new_state = False
        except hub.tool.boto3.exception.ClientError as e:
            result["comment"] = f"{e.__class__.__name__}: {e}"
            result["result"] = False
    else:
        try:
            ret = await hub.exec.boto3.client.ec2.create_internet_gateway(
                ctx,
                TagSpecifications=[{"ResourceType": "internet-gateway", "Tags": tags}]
                if tags
                else None,
            )
            result["result"] = ret["result"]
            if not result["result"]:
                result["comment"] = ret["comment"]
                return result
            name = ret["ret"]["InternetGateway"]["InternetGatewayId"]
            resource._id = name
            result["comment"] = f"Created '{name}'"
        except hub.tool.boto3.exception.ClientError as e:
            result["comment"] = f"{e.__class__.__name__}: {e}"
            result["result"] = False
        if vpc_id:
            try:
                ret = await hub.exec.boto3.client.ec2.attach_internet_gateway(
                    ctx, InternetGatewayId=name, VpcId=vpc_id[0]
                )
                result["result"] = ret["result"]
                if not result["result"]:
                    result["comment"] = ret["comment"]
                    result["result"] = False
                    return result
                result[
                    "comment"
                ] = f"Created '{name}' and attached to vpc '{vpc_id[0]}'"
            except hub.tool.boto3.exception.ClientError as e:
                result["result"] = False
                result[
                    "comment"
                ] = f"Created '{name}'. Attach to '{vpc_id[0]}' failed with error: {e}"
    try:
        if update_new_state:
            after = await hub.tool.boto3.resource.describe(resource)
            result["new_state"] = after
        else:
            result["new_state"] = before
    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 internet gateway. If resource is attached to VPC. then it is detached first and then deleted.

    Args:
        name(Text): The ID of the internet gateway.

    Request Syntax:
        [internet_gateway-id]:
          aws.ec2.internet_gateway.absent:
          - name: 'string'

    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: sls

           igw-54c83a2c:
            aws.ec2.internet_gateway.absent:
              - name: igw-54c83a2c
    """

    result = dict(comment="", old_state=None, new_state=None, name=name, result=True)
    resource = hub.tool.boto3.resource.create(ctx, "ec2", "InternetGateway", name)
    before = await hub.tool.boto3.resource.describe(resource)
    result["old_state"] = before
    if not before:
        result["comment"] = f"'{name}' already absent"
    elif ctx.get("test", False):
        result["comment"] = f"Would delete aws.ec2.internet_gateway {name}"
        return result
    else:
        try:
            if before["Attachments"]:
                resource.detach_from_vpc(VpcId=before["Attachments"][0]["VpcId"])
            ret = await hub.exec.boto3.client.ec2.delete_internet_gateway(
                ctx, InternetGatewayId=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["result"] = False
            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 internet gateways.


    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: bash

            $ idem describe aws.ec2.internet_gateway
    """

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

    for internet_gateway in ret["ret"]["InternetGateways"]:
        resource_id = internet_gateway.get("InternetGatewayId")
        resource_translated = []
        if internet_gateway.get("Tags"):
            resource_translated.append({"tags": internet_gateway.get("Tags")})
        if internet_gateway.get("Attachments"):
            resource_translated.append(
                {"vpc_id": [internet_gateway.get("Attachments")[0].get("VpcId")]}
            )
        result[resource_id] = {"aws.ec2.internet_gateway.present": resource_translated}
    return result
