// this file is @generated

{% set resource_type_name = resource.name | to_upper_camel_case -%}

{% for c in referenced_components -%}
import {
    type {{ c | to_upper_camel_case }},
    {{ c | to_upper_camel_case }}Serializer,
} from '../models/{{ c | to_lower_camel_case }}';
{% endfor -%}
{% for _, sub in resource.subresources | items -%}
import { {{ sub.name | to_upper_camel_case}} } from './{{ sub.name | to_lower_camel_case }}';
{% endfor -%}
import { HttpMethod, SvixRequest, SvixRequestContext } from "../request";
{# HACK: api_internal/message.ts generates the `messageInRaw` function that requires `MessageIn` -#}
import { type MessageIn, MessageInSerializer } from "../models/messageIn";

{% for op in resource.operations -%}
    {% if op | has_query_or_header_params -%}
    export interface {{ resource_type_name }}{{ op.name | to_upper_camel_case }}Options {
        {% for p in op.query_params -%}
            {% if p.description is defined -%}
                {{ p.description | to_doc_comment(style="js") }}
            {% endif -%}
            {% set field_ty = p.type.to_js() -%}
            {% if p.name == "iterator" %}{% set field_ty = "string | null" %}{% endif -%}
            {% if p.type.is_datetime() %}{% set field_ty = "Date | null"%}{% endif -%}
            {{ p.name | to_lower_camel_case }}{% if not p.required %}?{% endif %}: {{ field_ty }};
        {% endfor -%}
        {% for p in op.header_params -%}
            {% if p.description is defined -%}
                {{ p.description | to_doc_comment(style="js") }}
            {% endif -%}
            {% set field_ty = "string" -%}
            {{ p.name | to_lower_camel_case }}{% if not p.required %}?{% endif %}: {{ field_ty }};
        {% endfor -%}
    }

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

export class {{ resource_type_name }} {
    public constructor(private readonly requestCtx: SvixRequestContext) {}

    {% for name, sub in resource.subresources | items -%}
    public get {{ name | to_lower_camel_case }}() {
        return new {{ sub.name | to_upper_camel_case }}(this.requestCtx);
    }

    {% endfor -%}

    {% for op in resource.operations -%}
        {% set response_type =
            op.response_body_schema_name | default("void") | replace("_", "") -%}
        {{ op.description | with_javadoc_deprecation(op.deprecated) | to_doc_comment(style="js") }}
        public async {{ op.name | to_lower_camel_case }}(
            {# path parameters -#}
            {% for p in op.path_params -%}
                {{ p | to_lower_camel_case }}: string,
            {% endfor -%}

            {# body parameter interface -#}
            {% if op.request_body_schema_name is defined -%}
                {# could also default to an empty object for Patch types but an empty PATCH
                   is nonsensical, so we don't -#}
                {% if op.request_body_schema_name is not endingwith "Patch" -%}
                    {% set body_schema = api.types[op.request_body_schema_name] -%}
                    {% set default_empty_object
                        = body_schema.kind == "struct"
                            and body_schema.fields | selectattr("required") | length == 0 -%}
                {% endif -%}
                {% set field_name = op.request_body_schema_name | to_lower_camel_case -%}
                {{ field_name }}: {{ op.request_body_schema_name }}
                    {%- if default_empty_object %} = {}{% endif %},
            {% endif -%}

            {# query parameters -#}
            {% if op | has_query_or_header_params -%}
                {% set field_ty -%}
                    {{ resource_type_name }}{{ op.name | to_upper_camel_case }}Options
                {%- endset -%}
                options{% if not op | has_required_query_or_header_params %}?{% endif %}: {{ field_ty }},
            {% endif -%}
        ): Promise<{{ response_type }}> {
            const request = new SvixRequest(HttpMethod.{{ op.method | upper }}, "{{ op.path }}");

            {# path parameters -#}
            {% for p in op.path_params -%}
                request.setPathParam("{{ p }}", {{ p | to_lower_camel_case }});
            {% endfor -%}

            {# query parameters -#}
            {% if op.query_params | length > 0 -%}
            request.setQueryParams({
                {% for p in op.query_params -%}
                "{{ p.name }}":
                options{% if not p.required %}?{% endif %}.{{ p.name | to_lower_camel_case }}
                    {#- default with_content to false, it only defaults to true
                        server-side because of backwards-compatibility #}
                    {%- if p.name == "with_content" %} ?? false
                    {#- default expanded_statuses to true, it only defaults to false
                        server-side because of backwards-compatibility #}
                    {%- elif p.name == "expanded_statuses" %} ?? true{% endif %},
                {% endfor -%}
            });
            {% endif -%}

            {# header parameters -#}
            {% for p in op.header_params -%}
                request.setHeaderParam("{{ p.name }}", options?.{{ p.name | to_lower_camel_case }});
            {% endfor -%}

            {# body parameter -#}
            {% if op.request_body_schema_name is defined -%}
                request.setBody(
                    {{ op.request_body_schema_name | to_upper_camel_case }}Serializer._toJsonObject(
                        {{ op.request_body_schema_name | to_lower_camel_case }},
                    )
                );
            {% endif %}

            return await {% if op.response_body_schema_name is defined -%}
                request.send(
                    this.requestCtx,
                    {{ op.response_body_schema_name | to_upper_camel_case }}Serializer._fromJsonObject,
                )
            {% else %}
                request.sendNoResponseBody(this.requestCtx)
            {% endif -%};
        }

        {% set extra_path -%}
            api_extra/{{ resource.name | to_snake_case }}_{{ op.name | to_snake_case }}.ts
        {%- endset -%}
        {% include extra_path ignore missing %}

    {% endfor -%}
}

{% set extra_path -%}
    api_extra/{{ resource.name | to_snake_case }}.ts
{%- endset -%}
{% include extra_path ignore missing %}
