# This file is @generated
{% set api_mod_name %}{{ resource.name | to_snake_case }}_api{% endset -%}
{% set resource_class_name = resource.name | to_upper_camel_case -%}
{% set resource_type_name = resource.name | to_upper_camel_case -%}
import typing as t
from datetime import datetime
from dataclasses import dataclass
from deprecated import deprecated
from .common import ApiBaseAsync, ApiBaseSync, BaseOptions, serialize_params
from .. import models

{% for c in referenced_components -%}
from ..models import {{ c | to_upper_camel_case }}
{% endfor -%}
{% for _, sub in resource.subresources | items -%}
from .{{ sub.name | to_snake_case }} import (
    {{ sub.name | to_upper_camel_case }},
    {{ sub.name | to_upper_camel_case }}Async,
)
{% endfor %}


{# FIXME: need to understand how this template generates newlines and stop generating newlines #}
{% for op in resource.operations %}
    {%- if op | has_query_or_header_params %}
@dataclass
class {{ resource_type_name }}{{ op.name | to_upper_camel_case }}Options(BaseOptions):
        {%- for p in op.query_params %}
        {%- set p_type_prefix -%}
        {%- if p.type.is_schema_ref() -%}models.{%- endif %}
        {%- endset %}
            {%- if p.required %}
    {{ p.name }}: {{ p_type_prefix }}{{ p.type.to_python() }}
            {%- else %}
    {{ p.name }}: t.Optional[{{ p_type_prefix }}{{ p.type.to_python() }}] = None
            {%- endif -%}
            {%- if p.description is defined %}
    {{ p.description | to_doc_comment(style="python") }}
            {%- endif -%}
        {%- endfor %}
    {#- FIXME: hardcoding idempotency-key for now since that is the only header param #}
        {%- if op.header_params | length > 0 %}
    idempotency_key: t.Optional[str] = None
        {%- endif %}
        {%- if op.query_params | length > 0 %}
    def _query_params(self) -> t.Dict[str, str]:
        return serialize_params({
        {%- for p in op.query_params %}
            "{{ p.name }}": self.{{ p.name | to_snake_case }}
            {%- if p.name == "with_content" %} or False
            {%- elif p.name == "expanded_statuses"
                %} if self.{{ p.name | to_snake_case }} is not None else True
            {%- endif %},
        {%- endfor %}
        })
        {%- endif %}

        {%- if op.header_params | length > 0 %}
    def _header_params(self) -> t.Dict[str, str]:
        return serialize_params({
        {%- for p in op.header_params %}
            "{{ p.name }}": self.{{ p.name | to_snake_case }},
        {%- endfor %}
        })
        {%- endif %}

    {%- endif -%}
{%- endfor %}

{% if not (context is defined and context.api_internal) -%}
{% set api_resource_extra -%}
    api_extra/{{ resource.name | to_snake_case }}.py
{%- endset %}
{% include api_resource_extra ignore missing %}
{% endif -%}


{% for is_async in [true, false] %}
{% set sync_bit %}{% if is_async %}Async{% else %}Sync{% endif %}{% endset -%}
class {{ resource.name | to_upper_camel_case }}{% if is_async %}Async{% endif %}(ApiBase{{ sync_bit }}):
    {%- for name, sub in resource.subresources | items %}
    {%- set sub_type_name %}{{ sub.name | to_upper_camel_case }}{% if is_async %}Async{% endif %}{% endset %}
    @property
    def {{ name | to_snake_case }}(self) -> {{ sub_type_name }}:
        return {{ sub_type_name }}(self._client, self._httpx_client)

    {% endfor %}

    {%- if resource.operations | length > 0 %}
        {%- for op in resource.operations %}
            {% if op.response_body_schema_name is defined -%}
                {% set return_type = op.response_body_schema_name | to_upper_camel_case -%}
            {% else -%}
                {% set return_type = "None" -%}
            {% endif -%}
            {# FIXME: find a better way to deal with python's reserved keywords!, for now i do this hack #}
            {%- if op.name == "import" %}
                {%- set op_name = "import_" %}
            {%- else %}
                {%- set op_name = op.name | to_snake_case %}
            {%- endif %}
            {% if op.deprecated %}
    @deprecated
            {%- endif %}
            {%- if is_async -%}
                {%- set async = "async " %}
            {%- endif %}
    {{ async -}} def {{ op_name }}(self
            {#- path parameters are non optional strings #}
            {% for p in op.path_params -%}
        ,{{ p }}: str
            {% endfor -%}
            {# body parameter struct #}
            {%- if op.request_body_schema_name is defined %}
        ,{{ op.request_body_schema_name | to_snake_case }}: {{ op.request_body_schema_name }}
            {%- endif %}

            {# add query_options type #}
            {%- if op | has_query_or_header_params %}
            {% set resource_operation_option %}{{ resource_type_name }}{{ op.name | to_upper_camel_case }}Options{% endset %}
        ,options: {{ resource_operation_option }}{% if not op | has_required_query_or_header_params %} = (
            {{ resource_operation_option }}()
        ){% endif %}
            {%- endif %}
    ) -> {{ return_type }}:
            {% if op.description is defined -%}
    {{ op.description | to_doc_comment(style="python") }}
            {%- endif -%}
            {%- set internal_func_name -%}
                {% if is_async -%}
                _request_asyncio
                {%- else -%}
                _request_sync
                {%- endif -%}
            {%- endset %}
            {% if op.response_body_schema_name is defined -%}
            response =
            {%- endif -%}
            {%- if is_async %}await {% endif %}self.{{ internal_func_name }}(
                method="{{ op.method }}",
                path="{{ op.path }}"
                ,path_params={
                {%- for path_param in op.path_params %}
                    "{{ path_param }}":{{ path_param }},
                {% endfor -%}
                }
                {%- if op | has_query_or_header_params %}
                ,query_params=options._query_params()
                ,header_params=options._header_params()
                {%- endif %}
                {% if op.request_body_schema_name is defined -%}
                ,json_body={{ op.request_body_schema_name | to_snake_case }}.model_dump_json(exclude_unset=True, by_alias=True)
                {%- endif -%})
            {% if op.response_body_schema_name is defined -%}
            return {{ op.response_body_schema_name | to_upper_camel_case }}.model_validate(response.json())
            {% endif %}
            {% set api_operation_extra -%}
                {% if is_async -%}
                api_extra/{{ resource.name | to_snake_case }}_{{ op.name | to_snake_case }}_asyncio.py
                {%- else -%}
                api_extra/{{ resource.name | to_snake_case }}_{{ op.name | to_snake_case }}_sync.py
                {%- endif -%}
            {% endset %}
            {% set code %}{% include api_operation_extra ignore missing %}{% endset %}

{{ code | indent(4, true) }}
        {% endfor -%}
    {% endif %}
    {% if resource.subresources | length == 0 and resource.operations | length == 0 %}
    {# empty class with no members, so we have a pass here -#}
    pass
    {% endif %}
{% endfor %}
