{#
    This is a custom template derived from:
    https://github.com/openapi-generators/openapi-python-client/blob/v.0.10.7/openapi_python_client/templates/endpoint_module.py.jinja
#}
from typing import Any, Dict, List, Optional, Union, cast

import requests

from ...client import AuthenticatedClient, Client
from ...types import Response, UNSET, Unset

{% for relative in endpoint.relative_imports %}
{{ relative }}
{% endfor %}

{% from "endpoint_macros.py.jinja" import header_params, cookie_params, query_params, json_body, multipart_body, arguments, client, kwargs, parse_response %}

{% set return_string = endpoint.response_type() %}
{% set parsed_responses = (endpoint.responses | length > 0) and return_string != "Any" %}


QUERY_PARAMS = {
    {% for parameter in endpoint.query_parameters.values() %}
    "{{ parameter.name }}": {{ parameter.get_type_string(no_optional=True) }},
    {% endfor %}
}
{% if endpoint.form_body_class %}
REQUEST_BODY_TYPE = {{ endpoint.form_body_class.name }}
{% elif endpoint.json_body %}
REQUEST_BODY_TYPE = {{ endpoint.json_body.get_type_string() }}
{% endif %}

def _get_kwargs(
    {{ arguments(endpoint) | indent(4) }}
) -> Dict[str, Any]:
    url = "{}{{ endpoint.path }}".format(
        client.base_url,
        {%- for parameter in endpoint.path_parameters.values() -%}
        {{parameter.name}}={{parameter.python_name}},
        {%- endfor -%}
    )

    headers: Dict[str, Any] = client.get_headers()

    {{ cookie_params(endpoint) | indent(4) }}

    {{ query_params(endpoint) | indent(4) }}

    {{ json_body(endpoint) | indent(4) }}

    {{ multipart_body(endpoint) | indent(4) }}

    return {
        "url": url,
        "headers": headers,
        {# {% if endpoint.form_body_class %}
        "data": form_data.to_dict(),
        {% elif endpoint.multipart_body %}
        "files": {{ "multipart_" + endpoint.multipart_body.python_name }},
        {% elif endpoint.json_body %}
        "json": {{ "json_" + endpoint.json_body.python_name }},
        {% endif %} #}
        {% if endpoint.form_body_class %}
        "json": form_data.to_dict(),
        {% elif endpoint.json_body %}
        "json": {{ "json_" + endpoint.json_body.python_name }},
        {% elif endpoint.multipart_body %}
        "files": {{ "multipart_" + endpoint.multipart_body.python_name }},
        {% endif %}
        {% if endpoint.query_parameters %}
        "params": params,
        {% endif %}
    }


{% if parsed_responses %}
def _parse_response(*, response: requests.Response) -> Optional[{{ return_string }}]:
    {% for response in endpoint.responses %}
    if response.status_code == {{ response.status_code }}:
        {% if response.prop.template %}
            {% from "property_templates/" + response.prop.template import construct %}
        {{ construct(response.prop, response.source) | indent(8) }}
        {% else %}
        {{ response.prop.python_name }} = {{ response.source }}
        {% endif %}
        return {{ response.prop.python_name }}
    {% endfor %}
    return None
{% endif %}


def _build_response(*, response: requests.Response) -> Response[{{ return_string }}]:
    return Response(
        status_code=response.status_code,
        content=response.content,
        headers=response.headers,
        {% if parsed_responses %}
        parsed=_parse_response(response=response),
        {% else %}
        parsed=None,
        {% endif %}
    )


def sync_detailed(
    {{ arguments(endpoint) | indent(4) }}
) -> Response[{{ return_string }}]:
    kwargs = _get_kwargs(
        {{ kwargs(endpoint) }}
    )

    response = requests.{{ endpoint.method }}(
        verify=client.verify_ssl,
        auth=client.auth,
        timeout=client.timeout,
        **kwargs,
    )
    response.raise_for_status()

    return _build_response(response=response)

{% if parsed_responses %}
def sync(
    {{ arguments(endpoint) | indent(4) }}
) -> Optional[{{ return_string }}]:
    """ {{ endpoint.description }} """

    return sync_detailed(
        {{ kwargs(endpoint) }}
    ).parsed
{% endif %}

async def async_detailed(
    {{ arguments(endpoint) | indent(4) }}
) -> Response[{{ return_string }}]:
    kwargs = _get_kwargs(
        {{ kwargs(endpoint) }}
    )

    async with client.get_async_session().{{ endpoint.method }}(
        verify_ssl=client.verify_ssl, raise_for_status=True, **kwargs
    ) as response:
        content = await response.read()
        resp = requests.Response()
        resp.status_code = response.status
        resp._content = content

    return _build_response(response=resp)

{% if parsed_responses %}
async def async_(
    {{ arguments(endpoint) | indent(4) }}
) -> Optional[{{ return_string }}]:
    """ {{ endpoint.description }} """

    return (await async_detailed(
        {{ kwargs(endpoint) }}
    )).parsed
{% endif %}

