{{>partial_header}}
package {{packageName}}

{{#operations}}
import (
	"bytes"
	"context"
	"io"
	"net/http"
	"net/url"
{{#imports}}	"{{import}}"
{{/imports}}
)

// Linger please
var (
	_ context.Context
)
{{#generateInterfaces}}

type {{classname}} interface {
	{{#operation}}

	/*
	 * {{operationId}}{{#summary}} {{{.}}}{{/summary}}{{^summary}} Method for {{operationId}}{{/summary}}
	{{#notes}}
	 * {{{unescapedNotes}}}
	{{/notes}}
	 * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().{{#pathParams}}
	 * @param {{paramName}}{{#description}} {{{.}}}{{/description}}{{/pathParams}}
	 * @return {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request
	 */
	{{{nickname}}}(ctx context.Context{{#pathParams}}, {{paramName}} {{{dataType}}}{{/pathParams}}) {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request

	/*
	 * {{nickname}}Execute executes the request{{#returnType}}
	 * @return {{{.}}}{{/returnType}}
	 */
	{{nickname}}Execute(r {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request) ({{#returnType}}{{^isArray}}{{^returnTypeIsPrimitive}}*{{/returnTypeIsPrimitive}}{{/isArray}}{{{.}}}, {{/returnType}}*http.Response, error)
	{{/operation}}
}
{{/generateInterfaces}}

// {{classname}}Service {{classname}} service
type {{classname}}Service service
{{#operation}}

type {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request struct {
	ctx context.Context{{#generateInterfaces}}
	ApiService {{classname}}
{{/generateInterfaces}}{{^generateInterfaces}}
	ApiService *{{classname}}Service
{{/generateInterfaces}}
{{#allParams}}
	{{paramName}} {{^isPathParam}}*{{/isPathParam}}{{{dataType}}}
{{/allParams}}
}
{{#allParams}}{{^isPathParam}}
func (r {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request) {{vendorExtensions.x-export-param-name}}({{paramName}} {{{dataType}}}) {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request {
	r.{{paramName}} = &{{paramName}}
	return r
}{{/isPathParam}}{{/allParams}}

func (r {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request) Execute() ({{#returnType}}{{^isArray}}{{^returnTypeIsPrimitive}}*{{/returnTypeIsPrimitive}}{{/isArray}}{{{.}}}, {{/returnType}}*http.Response, error) {
	return r.ApiService.{{nickname}}Execute(r)
}

/*
 * {{operationId}}{{#summary}} {{{.}}}{{/summary}}{{^summary}} Method for {{operationId}}{{/summary}}
{{#notes}}
 * {{{unescapedNotes}}}
{{/notes}}
 * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().{{#pathParams}}
 * @param {{paramName}}{{#description}} {{{.}}}{{/description}}{{/pathParams}}
 * @return {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request
 */
func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#pathParams}}, {{paramName}} {{{dataType}}}{{/pathParams}}) {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request {
	return {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request{
		ApiService: a,
		ctx: ctx,{{#pathParams}}
		{{paramName}}: {{paramName}},{{/pathParams}}
	}
}

/*
 * Execute executes the request{{#returnType}}
 * @return {{{.}}}{{/returnType}}
 */
func (a *{{{classname}}}Service) {{nickname}}Execute(r {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request) ({{#returnType}}{{^isArray}}{{^returnTypeIsPrimitive}}*{{/returnTypeIsPrimitive}}{{/isArray}}{{{.}}}, {{/returnType}}*http.Response, error) {
	var (
		localVarHTTPMethod   = http.Method{{httpMethod}}
		localVarPostBody     interface{}
		localVarFormFileName string
		localVarFileName     string
		localVarFileBytes    []byte
		{{#returnType}}
		localVarReturnValue  {{^isArray}}{{^returnTypeIsPrimitive}}*{{/returnTypeIsPrimitive}}{{/isArray}}{{{.}}}
		{{/returnType}}
	)

	localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "{{{classname}}}Service.{{{nickname}}}")
	if err != nil {
		return {{#returnType}}localVarReturnValue, {{/returnType}}nil, &GenericOpenAPIError{error: err.Error()}
	}

	localVarPath := localBasePath + "{{{path}}}"{{#pathParams}}
	localVarPath = strings.Replace(localVarPath, "{"+"{{baseName}}"+"}", url.PathEscape(parameterToString(r.{{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}")), -1){{/pathParams}}

	localVarHeaderParams := make(map[string]string)
	localVarQueryParams := url.Values{}
	localVarFormParams := url.Values{}
	{{#allParams}}
	{{#required}}
	{{^isPathParam}}
	if r.{{paramName}} == nil {
		return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} is required and must be specified")
	}
	{{/isPathParam}}
	{{#minItems}}
	if len({{^isPathParam}}*{{/isPathParam}}r.{{paramName}}) < {{minItems}} {
		return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must have at least {{minItems}} elements")
	}
	{{/minItems}}
	{{#maxItems}}
	if len({{^isPathParam}}*{{/isPathParam}}r.{{paramName}}) > {{maxItems}} {
		return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must have less than {{maxItems}} elements")
	}
	{{/maxItems}}
	{{#minLength}}
	if strlen({{^isPathParam}}*{{/isPathParam}}r.{{paramName}}) < {{minLength}} {
		return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must have at least {{minLength}} elements")
	}
	{{/minLength}}
	{{#maxLength}}
	if strlen({{^isPathParam}}*{{/isPathParam}}r.{{paramName}}) > {{maxLength}} {
		return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must have less than {{maxLength}} elements")
	}
	{{/maxLength}}
	{{#minimum}}
	{{#isString}}
	{{paramName}}Txt, err := atoi({{^isPathParam}}*{{/isPathParam}}r.{{paramName}})
	if {{paramName}}Txt < {{minimum}} {
	{{/isString}}
	{{^isString}}
	if {{^isPathParam}}*{{/isPathParam}}r.{{paramName}} < {{minimum}} {
	{{/isString}}
		return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must be greater than {{minimum}}")
	}
	{{/minimum}}
	{{#maximum}}
	{{#isString}}
	{{paramName}}Txt, err := atoi({{^isPathParam}}*{{/isPathParam}}r.{{paramName}})
	if {{paramName}}Txt > {{maximum}} {
	{{/isString}}
	{{^isString}}
	if {{^isPathParam}}*{{/isPathParam}}r.{{paramName}} > {{maximum}} {
	{{/isString}}
		return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must be less than {{maximum}}")
	}
	{{/maximum}}
	{{/required}}
	{{/allParams}}

	{{#queryParams}}
	{{#required}}
	{{#isCollectionFormatMulti}}
	{
		t := *r.{{paramName}}
		if reflect.TypeOf(t).Kind() == reflect.Slice {
			s := reflect.ValueOf(t)
			for i := 0; i < s.Len(); i++ {
				localVarQueryParams.Add("{{baseName}}", parameterToString(s.Index(i), "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}"))
			}
		} else {
			localVarQueryParams.Add("{{baseName}}", parameterToString(t, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}"))
		}
	}
	{{/isCollectionFormatMulti}}
	{{^isCollectionFormatMulti}}
	localVarQueryParams.Add("{{baseName}}", parameterToString(*r.{{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}"))
	{{/isCollectionFormatMulti}}
	{{/required}}
	{{^required}}
	if r.{{paramName}} != nil {
	{{#isCollectionFormatMulti}}
		t := *r.{{paramName}}
		if reflect.TypeOf(t).Kind() == reflect.Slice {
			s := reflect.ValueOf(t)
			for i := 0; i < s.Len(); i++ {
				localVarQueryParams.Add("{{baseName}}", parameterToString(s.Index(i), "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}"))
			}
		} else {
			localVarQueryParams.Add("{{baseName}}", parameterToString(t, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}"))
		}
	{{/isCollectionFormatMulti}}
	{{^isCollectionFormatMulti}}
		localVarQueryParams.Add("{{baseName}}", parameterToString(*r.{{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}"))
	{{/isCollectionFormatMulti}}
	}
	{{/required}}
	{{/queryParams}}
	// to determine the Content-Type header
{{=<% %>=}}
	localVarHTTPContentTypes := []string{<%#consumes%>"<%&mediaType%>"<%^-last%>, <%/-last%><%/consumes%>}
<%={{ }}=%>

	// set Content-Type header
	localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
	if localVarHTTPContentType != "" {
		localVarHeaderParams["Content-Type"] = localVarHTTPContentType
	}

	// to determine the Accept header
{{=<% %>=}}
	localVarHTTPHeaderAccepts := []string{<%#produces%>"<%&mediaType%>"<%^-last%>, <%/-last%><%/produces%>}
<%={{ }}=%>

	// set Accept header
	localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
	if localVarHTTPHeaderAccept != "" {
		localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
	}
{{#headerParams}}
	{{#required}}
	localVarHeaderParams["{{baseName}}"] = parameterToString(*r.{{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}")
	{{/required}}
	{{^required}}
	if r.{{paramName}} != nil {
		localVarHeaderParams["{{baseName}}"] = parameterToString(*r.{{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}")
	}
	{{/required}}
{{/headerParams}}
{{#formParams}}
{{#isFile}}
	localVarFormFileName = "{{baseName}}"
{{#required}}
	localVarFile := *r.{{paramName}}
{{/required}}
{{^required}}
	var localVarFile {{dataType}}
	if r.{{paramName}} != nil {
		localVarFile = *r.{{paramName}}
	}
{{/required}}
	if localVarFile != nil {
		fbs, _ := io.ReadAll(localVarFile)
		localVarFileBytes = fbs
		localVarFileName = localVarFile.Name()
		localVarFile.Close()
	}
{{/isFile}}
{{^isFile}}
{{#required}}
	localVarFormParams.Add("{{baseName}}", parameterToString(*r.{{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}"))
{{/required}}
{{^required}}
{{#isModel}}
	if r.{{paramName}} != nil {
		paramJson, err := parameterToJson(*r.{{paramName}})
		if err != nil {
			return {{#returnType}}localVarReturnValue, {{/returnType}}nil, err
		}
		localVarFormParams.Add("{{baseName}}", paramJson)
	}
{{/isModel}}
{{^isModel}}
	if r.{{paramName}} != nil {
		localVarFormParams.Add("{{baseName}}", parameterToString(*r.{{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}"))
	}
{{/isModel}}
{{/required}}
{{/isFile}}
{{/formParams}}
{{#bodyParams}}
	// body params
	localVarPostBody = r.{{paramName}}
{{/bodyParams}}
{{#authMethods}}
{{#isApiKey}}
{{^isKeyInCookie}}
	if r.ctx != nil {
		// API Key Authentication
		if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok {
			{{#vendorExtensions.x-auth-id-alias}}
			if apiKey, ok := auth["{{.}}"]; ok {
				var key string
				if prefix, ok := auth["{{name}}"]; ok && prefix.Prefix != "" {
					key = prefix.Prefix + " " + apiKey.Key
				} else {
					key = apiKey.Key
				}
			{{/vendorExtensions.x-auth-id-alias}}
			{{^vendorExtensions.x-auth-id-alias}}
			if apiKey, ok := auth["{{name}}"]; ok {
				var key string
				if apiKey.Prefix != "" {
					key = apiKey.Prefix + " " + apiKey.Key
				} else {
					key = apiKey.Key
				}
			{{/vendorExtensions.x-auth-id-alias}}
				{{#isKeyInHeader}}
				localVarHeaderParams["{{keyParamName}}"] = key
				{{/isKeyInHeader}}
				{{#isKeyInQuery}}
				localVarQueryParams.Add("{{keyParamName}}", key)
				{{/isKeyInQuery}}
			}
		}
	}
{{/isKeyInCookie}}
{{/isApiKey}}
{{/authMethods}}
	req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
	if err != nil {
		return {{#returnType}}localVarReturnValue, {{/returnType}}nil, err
	}

	localVarHTTPResponse, err := a.client.callAPI(req)
	if err != nil || localVarHTTPResponse == nil {
		return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHTTPResponse, err
	}

	localVarBody, err := io.ReadAll(io.LimitReader(localVarHTTPResponse.Body, 1024*1024))
	localVarHTTPResponse.Body.Close()
	localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
	if err != nil {
		return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHTTPResponse, err
	}

	if localVarHTTPResponse.StatusCode >= 300 {
		newErr := &GenericOpenAPIError{
			body:  localVarBody,
			error: localVarHTTPResponse.Status,
		}
		{{#responses}}
		{{#dataType}}
		{{^is1xx}}
		{{^is2xx}}
		{{^wildcard}}
		if localVarHTTPResponse.StatusCode == {{{code}}} {
		{{/wildcard}}
			var v {{{dataType}}}
			err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
			if err != nil {
				newErr.error = err.Error()
				return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHTTPResponse, newErr
			}
			newErr.model = v
			{{^-last}}
			return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHTTPResponse, newErr
			{{/-last}}
		{{^wildcard}}
		}
		{{/wildcard}}
		{{/is2xx}}
		{{/is1xx}}
		{{/dataType}}
		{{/responses}}
		return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHTTPResponse, newErr
	}

	{{#returnType}}
	err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
	if err != nil {
		newErr := &GenericOpenAPIError{
			body:  localVarBody,
			error: err.Error(),
		}
		return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHTTPResponse, newErr
	}

	{{/returnType}}
	return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHTTPResponse, nil
}
{{/operation}}
{{/operations}}
