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


"""
from collections import OrderedDict
from typing import Any
from typing import Dict


__contracts__ = ["resource"]


async def present(
    hub,
    ctx,
    name: str,
    resource_group_name: str,
    route_table_name: str,
    route_name: str,
    parameters: dict = None,
    force_update: bool = False,
) -> dict:
    r"""
    **Autogenerated function**

    Create or update Routes

    Args:
        name(str): The identifier for this state.
        resource_group_name(str): The name of the resource group.
        route_table_name(str): The name of the route table.
        route_name(str): The name of the route.
        parameters(dict, optional): API request payload parameters. Defaults to {}.
        force_update(bool, optional): If PUT operation should be used instead of PATCH operation during resource update. Defaults to False.

    Returns:
        dict

    Examples:

        .. code-block:: sls

            resource_is_present:
              azure.virtual_networks.routes.present:
                - name: value
                - resource_group_name: value
                - route_table_name: value
                - route_name: value
    """
    if parameters is None:
        parameters = {}

    subscription_id = ctx.acct.subscription_id
    response_get = await hub.exec.request.json.get(
        ctx,
        url=f"{hub.exec.azure.URL}/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.Network/routeTables/{route_table_name}/routes/{route_name}?api-version=2021-03-01",
        success_codes=[200],
    )

    if force_update:
        if ctx.get("test", False):
            return dict(
                name=name,
                result=True,
                comment="Would force to update azure.virtual_networks.routes",
            )
        response_force_put = await hub.exec.request.json.put(
            ctx,
            url=f"{hub.exec.azure.URL}/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.Network/routeTables/{route_table_name}/routes/{route_name}?api-version=2021-03-01",
            success_codes=[200, 201],
            json=parameters,
        )
        if response_force_put["result"]:
            old_resource = response_get["ret"] if response_get["result"] else None
            return dict(
                name=name,
                result=True,
                old_state=old_resource,
                new_state=response_force_put["ret"],
                comment=response_force_put["comment"],
            )
        else:
            hub.log.debug(
                f"Could not force to update Routes {response_force_put['comment']} {response_force_put['ret']}"
            )
            return dict(
                name=name,
                result=False,
                comment=response_force_put["comment"],
                error=response_force_put["ret"],
            )

    if not response_get["result"]:
        if ctx.get("test", False):
            return dict(
                name=name,
                result=True,
                comment="Would create azure.virtual_networks.routes",
            )

        if response_get["status"] == 404:
            # PUT operation to create a resource
            response_put = await hub.exec.request.json.put(
                ctx,
                url=f"{hub.exec.azure.URL}/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.Network/routeTables/{route_table_name}/routes/{route_name}?api-version=2021-03-01",
                success_codes=[200, 201],
                json=parameters,
            )

            if not response_put["result"]:
                hub.log.debug(
                    f"Could not create Routes {response_put['comment']} {response_put['ret']}"
                )
                return dict(
                    name=name,
                    result=False,
                    comment=response_put["comment"],
                    error=response_put["ret"],
                )

            return dict(
                name=name,
                result=True,
                old_state=None,
                new_state=response_put["ret"],
                comment=response_put["comment"],
            )
        else:
            hub.log.debug(
                f"Could not get Routes {response_get['comment']} {response_get['ret']}"
            )
            return dict(
                name=name,
                result=False,
                comment=response_get["comment"],
                error=response_get["ret"],
            )

    # No update operation on Routes since Azure does not have PATCH api on Routes
    return dict(
        name=name,
        result=True,
        old_state=response_get["ret"],
        new_state=response_get["ret"],
        comment=response_get["comment"],
    )


async def absent(
    hub,
    ctx,
    name: str,
    resource_group_name: str,
    route_table_name: str,
    route_name: str,
) -> dict:
    r"""
    **Autogenerated function**

    Delete Routes

    Args:
        name(str): The identifier for this state.
        resource_group_name(str): The name of the resource group.
        route_table_name(str): The name of the route table.
        route_name(str): The name of the route.

    Returns:
        dict

    Examples:

        .. code-block:: sls

            resource_is_absent:
              azure.virtual_networks.routes.absent:
                - name: value
                - resource_group_name: value
                - route_table_name: value
                - route_name: value
    """

    subscription_id = ctx.acct.subscription_id
    response_get = await hub.exec.request.json.get(
        ctx,
        url=f"{hub.exec.azure.URL}/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.Network/routeTables/{route_table_name}/routes/{route_name}?api-version=2021-03-01",
        success_codes=[200],
    )
    if response_get["result"]:
        if ctx.get("test", False):
            return dict(
                name=name,
                result=True,
                comment="Would delete azure.virtual_networks.routes",
            )

        existing_resource = response_get["ret"]
        response_delete = await hub.exec.request.raw.delete(
            ctx,
            url=f"{hub.exec.azure.URL}/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.Network/routeTables/{route_table_name}/routes/{route_name}?api-version=2021-03-01",
            success_codes=[200, 202, 204],
        )

        if not response_delete["result"]:
            hub.log.debug(
                f"Could not delete Routes {response_delete['comment']} {response_delete['ret']}"
            )
            return dict(
                name=name,
                result=False,
                comment=response_delete["comment"],
                error=response_delete["ret"],
            )

        return dict(
            name=name,
            result=True,
            old_state=existing_resource,
            new_state={},
            comment=response_delete["comment"],
        )
    elif response_get["status"] == 404:
        # If Azure returns 'Not Found' error, it means the resource has been absent.
        return dict(
            name=name,
            result=True,
            old_state=None,
            new_state=None,
            comment=f"'{name}' already absent",
        )
    else:
        hub.log.debug(
            f"Could not get Routes {response_get['comment']} {response_get['ret']}"
        )
        return dict(
            name=name,
            result=False,
            comment=response_get["comment"],
            error=response_get["ret"],
        )


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


    List all Routes under the same subscription


    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: bash

            $ idem describe azure.virtual_networks.routes
    """

    result = {}
    subscription_id = ctx.acct.subscription_id
    uri_parameters = OrderedDict(
        {
            "resourceGroups": "resource_group_name",
            "routeTables": "route_table_name",
            "routes": "route_name",
        }
    )
    async for route_tables_page_result in hub.tool.azure.request.paginate(
        ctx,
        url=f"{hub.exec.azure.URL}/subscriptions/{subscription_id}/providers/Microsoft.Network/routeTables?api-version=2021-03-01",
        success_codes=[200],
    ):
        route_tables_list = route_tables_page_result.get("value", None)
        if route_tables_list:
            for route_table in route_tables_list:
                url = f"{hub.exec.azure.URL}/{route_table.get('id')}/routes?api-version=2021-03-01"
                response_get = await hub.exec.request.json.get(
                    ctx,
                    url=url,
                    success_codes=[200],
                )
                if response_get["result"]:
                    resource_list = response_get["ret"].get("value", list())
                    for resource in resource_list:
                        uri_parameter_values = hub.tool.azure.uri.get_parameter_value(
                            resource["id"], uri_parameters
                        )
                        result[resource["id"]] = {
                            f"azure.virtual_networks.routes.present": uri_parameter_values
                            + [{"parameters": resource}]
                        }
                else:
                    raise ValueError(
                        f"Error on requesting GET {url} with status code {response_get['status_code']}:"
                        f" {response_get.get('ret', '')}"
                    )
    return result
