package {{package}};

import {{invokerPackage}}.ApiCallback;
import {{invokerPackage}}.ApiClient;
import {{invokerPackage}}.ApiException;
import {{invokerPackage}}.Configuration;
import {{invokerPackage}}.Pair;

import {{modelPackage}}.*;

import com.google.gson.reflect.TypeToken;

import com.squareup.okhttp.Call;

import java.lang.reflect.Type;

import java.util.*;

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

import java.io.File;
import java.util.Map;
import java.util.HashMap;

{{#operations}}
public class {{classname}} {
  private ApiClient {{localVariablePrefix}}apiClient;

  public {{classname}}() {
    this(Configuration.getDefaultApiClient());
  }

  public {{classname}}(ApiClient apiClient) {
    this.{{localVariablePrefix}}apiClient = apiClient;
  }

  public ApiClient getApiClient() {
    return {{localVariablePrefix}}apiClient;
  }

  public void setApiClient(ApiClient apiClient) {
    this.{{localVariablePrefix}}apiClient = apiClient;
  }

  {{#operation}}
  /* Build call for {{nickname}} */
  private Call {{nickname}}Call({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
    Object {{localVariablePrefix}}postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
    {{#allParams}}{{#required}}
    // verify the required parameter '{{paramName}}' is set
    if ({{paramName}} == null) {
       throw new ApiException("Missing the required parameter '{{paramName}}' when calling {{nickname}}(Async)");
    }
    {{/required}}{{/allParams}}

    // create path and map variables
    String {{localVariablePrefix}}path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}
      .replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};

    List<Pair> {{localVariablePrefix}}queryParams = new ArrayList<Pair>();{{#queryParams}}
    if ({{paramName}} != null)
      {{localVariablePrefix}}queryParams.addAll({{localVariablePrefix}}apiClient.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));{{/queryParams}}

    Map<String, String> {{localVariablePrefix}}headerParams = new HashMap<String, String>();{{#headerParams}}
    if ({{paramName}} != null)
      {{localVariablePrefix}}headerParams.put("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}}));{{/headerParams}}

    Map<String, Object> {{localVariablePrefix}}formParams = new HashMap<String, Object>();{{#formParams}}
    if ({{paramName}} != null)
      {{localVariablePrefix}}formParams.put("{{baseName}}", {{paramName}});{{/formParams}}

    final String[] {{localVariablePrefix}}accepts = {
      {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
    };
    final String {{localVariablePrefix}}accept = {{localVariablePrefix}}apiClient.selectHeaderAccept({{localVariablePrefix}}accepts);
    if ({{localVariablePrefix}}accept != null) {{localVariablePrefix}}headerParams.put("Accept", {{localVariablePrefix}}accept);

    final String[] {{localVariablePrefix}}contentTypes = {
      {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
    };
    final String {{localVariablePrefix}}contentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}contentTypes);
    {{localVariablePrefix}}headerParams.put("Content-Type", {{localVariablePrefix}}contentType);

    String[] {{localVariablePrefix}}authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
    return {{localVariablePrefix}}apiClient.buildCall({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}authNames);
  }

  /**
   * {{summary}}
   * {{notes}}{{#allParams}}
   * @param {{paramName}} {{description}}{{/allParams}}{{#returnType}}
   * @return {{{returnType}}}{{/returnType}}
   */
  public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
    Call {{localVariablePrefix}}call = {{nickname}}Call({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
    {{#returnType}}Type {{localVariablePrefix}}returnType = new TypeToken<{{{returnType}}}>(){}.getType();
    return {{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call, {{localVariablePrefix}}returnType);{{/returnType}}{{^returnType}}{{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call);{{/returnType}}
  }

  /**
   * {{summary}} (asynchronously)
   * {{notes}}{{#allParams}}
   * @param {{paramName}} {{description}}{{/allParams}}
   * @param callback The callback to be executed when the API call finishes
   * @return The request call
   */
  public Call {{nickname}}Async({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}ApiCallback<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{localVariablePrefix}}callback) throws ApiException {
    Call {{localVariablePrefix}}call = {{nickname}}Call({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
    {{#returnType}}Type {{localVariablePrefix}}returnType = new TypeToken<{{{returnType}}}>(){}.getType();
    {{localVariablePrefix}}apiClient.executeAsync({{localVariablePrefix}}call, {{localVariablePrefix}}returnType, {{localVariablePrefix}}callback);{{/returnType}}{{^returnType}}{{localVariablePrefix}}apiClient.executeAsync({{localVariablePrefix}}call, {{localVariablePrefix}}callback);{{/returnType}}
    return {{localVariablePrefix}}call;
  }
  {{/operation}}
}
{{/operations}}
