{{>licenseInfo}}
package {{apiPackage}}

{{#imports}}import {{import}}
{{/imports}}

import {{packageName}}.infrastructure.*
import io.ktor.client.HttpClientConfig
import io.ktor.client.request.forms.formData
import io.ktor.client.engine.HttpClientEngine
import io.ktor.http.ParametersBuilder
{{#gson}}
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import java.text.DateFormat
{{/gson}}
{{#jackson}}
import com.fasterxml.jackson.databind.ObjectMapper
{{/jackson}}

{{#operations}}
    {{#nonPublicApi}}internal {{/nonPublicApi}}open class {{classname}}(
    baseUrl: String = ApiClient.BASE_URL,
    httpClientEngine: HttpClientEngine? = null,
    httpClientConfig: ((HttpClientConfig<*>) -> Unit)? = null,
    {{#gson}}
    jsonBlock: GsonBuilder.() -> Unit = ApiClient.JSON_DEFAULT,
    {{/gson}}
    {{#jackson}}
    jsonBlock: ObjectMapper.() -> Unit = ApiClient.JSON_DEFAULT,
    {{/jackson}}
    ) : ApiClient(
        baseUrl,
        httpClientEngine,
        httpClientConfig,
        {{#gson}}
        jsonBlock,
        {{/gson}}
        {{#jackson}}
        jsonBlock,
        {{/jackson}}
    ) {

    {{#operation}}
        /**
        * {{summary}}
        * {{notes}}
        {{#allParams}} * @param {{{paramName}}} {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
        {{/allParams}} * @return {{{returnType}}}{{^returnType}}void{{/returnType}}
        */
        {{#returnType}}
            @Suppress("UNCHECKED_CAST")
        {{/returnType}}
        open suspend fun {{operationId}}({{#allParams}}{{{paramName}}}: {{{dataType}}}{{^required}}?{{/required}}{{^-last}}, {{/-last}}{{/allParams}}): HttpResponse<{{{returnType}}}{{^returnType}}Unit{{/returnType}}> {

            val localVariableAuthNames = listOf<String>({{#authMethods}}"{{name}}"{{^-last}}, {{/-last}}{{/authMethods}})

            val localVariableBody = {{#hasBodyParam}}{{#bodyParam}}{{{paramName}}}{{/bodyParam}}{{/hasBodyParam}}
        {{^hasBodyParam}}
            {{#hasFormParams}}
                {{#isMultipart}}
                        formData {
                    {{#formParams}}
                        {{#isFile}}
                        {{{paramName}}}?.apply { append("{{{baseName}}}", {{{paramName}}}) }
                        {{/isFile}}
                        {{^isFile}}
                        {{^isArray}}
                        {{^isString}}
                        {{^isNumber}}
                        {{{paramName}}}?.apply { append("{{{baseName}}}", {{{paramName}}}.toString()) }
                        {{/isNumber}}
                        {{#isNumber}}
                        {{{paramName}}}?.apply { append("{{{baseName}}}", {{{paramName}}}) }
                        {{/isNumber}}
                        {{/isString}}
                        {{#isString}}
                        {{{paramName}}}?.apply { append("{{{baseName}}}", {{{paramName}}}) }
                        {{/isString}}
                        {{/isArray}}
                        {{#isArray}}
                        for (x in {{paramName}} ?: listOf()) {
                            append("{{{baseName}}}", x.toString())
                        }
                        {{/isArray}}
                        {{/isFile}}
                    {{/formParams}}
                        }
                {{/isMultipart}}
                {{^isMultipart}}
                        ParametersBuilder().also {
                    {{#formParams}}
                        {{#isFile}}
                        {{{paramName}}}?.apply { it.append("{{{baseName}}}", {{{paramName}}}) }
                        {{/isFile}}
                        {{^isFile}}
                        {{^isArray}}
                        {{^isString}}
                        {{^isNumber}}
                        {{{paramName}}}?.apply { it.append("{{{baseName}}}", {{{paramName}}}.toString()) }
                        {{/isNumber}}
                        {{#isNumber}}
                        {{{paramName}}}?.apply { it.append("{{{baseName}}}", {{{paramName}}}) }
                        {{/isNumber}}
                        {{/isString}}
                        {{#isString}}
                        {{{paramName}}}?.apply { it.append("{{{baseName}}}", {{{paramName}}}) }
                        {{/isString}}
                        {{/isArray}}
                        {{#isArray}}
                        for (x in {{paramName}} ?: listOf()) {
                            append("{{{baseName}}}", x.toString())
                        }
                        {{/isArray}}
                        {{/isFile}}
                    {{/formParams}}
                        }.build()
                {{/isMultipart}}
            {{/hasFormParams}}
            {{^hasFormParams}}
                    io.ktor.client.utils.EmptyContent
            {{/hasFormParams}}
        {{/hasBodyParam}}

            val localVariableQuery = mutableMapOf<String, List<String>>()
        {{#queryParams}}
            {{{paramName}}}?.apply { localVariableQuery["{{baseName}}"] = {{#isContainer}}toMultiValue(this, "{{collectionFormat}}"){{/isContainer}}{{^isContainer}}listOf("${{{paramName}}}"){{/isContainer}} }
        {{/queryParams}}

            val localVariableHeaders = mutableMapOf<String, String>()
        {{#headerParams}}
            {{{paramName}}}?.apply { localVariableHeaders["{{baseName}}"] = {{#isContainer}}this.joinToString(separator = collectionDelimiter("{{collectionFormat}}")){{/isContainer}}{{^isContainer}}this.toString(){{/isContainer}} }
        {{/headerParams}}

            val localVariableConfig = RequestConfig<kotlin.Any?>(
            RequestMethod.{{httpMethod}},
            "{{path}}"{{#pathParams}}.replace("{" + "{{baseName}}" + "}", "${{{paramName}}}"){{/pathParams}},
            query = localVariableQuery,
            headers = localVariableHeaders,
            requiresAuthentication = {{#hasAuthMethods}}true{{/hasAuthMethods}}{{^hasAuthMethods}}false{{/hasAuthMethods}},
            )

            return {{#hasBodyParam}}jsonRequest{{/hasBodyParam}}{{^hasBodyParam}}{{#hasFormParams}}{{#isMultipart}}multipartFormRequest{{/isMultipart}}{{^isMultipart}}urlEncodedFormRequest{{/isMultipart}}{{/hasFormParams}}{{^hasFormParams}}request{{/hasFormParams}}{{/hasBodyParam}}(
            localVariableConfig,
            localVariableBody,
            localVariableAuthNames
            ).wrap()
            }

    {{/operation}}
        }
{{/operations}}
