/**
 * OpenAPI Petstore
 * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
 *
 * The version of the OpenAPI document: 1.0.0
 * 
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

package org.openapitools.client.api;

import java.util.Objects;
import org.openapitools.client.ApiResponse;

import com.fasterxml.jackson.databind.ObjectMapper;

import io.helidon.common.GenericType;
import io.helidon.common.http.MediaType;
import io.helidon.common.reactive.Single;
import io.helidon.config.Config;
import io.helidon.media.common.MediaSupport;

import io.helidon.media.jackson.JacksonSupport;
import io.helidon.webclient.WebClientRequestBuilder;
import io.helidon.webclient.WebClientResponse;

import org.openapitools.client.ApiClient;

import java.math.BigDecimal;
import org.openapitools.client.model.Client;
import org.openapitools.client.model.EnumClass;
import org.openapitools.client.model.FakeBigDecimalMap200Response;
import java.io.File;
import org.openapitools.client.model.FileSchemaTestClass;
import org.openapitools.client.model.HealthCheckResult;
import java.util.List;
import java.time.LocalDate;
import java.util.Map;
import java.time.OffsetDateTime;
import org.openapitools.client.model.OuterComposite;
import org.openapitools.client.model.OuterObjectWithEnumProperty;
import org.openapitools.client.model.Pet;
import org.openapitools.client.model.User;
import java.util.ArrayList;
import org.openapitools.client.Pair;
import java.util.StringJoiner;
import io.helidon.webclient.WebClientRequestHeaders;

/**
 * OpenAPI Petstore
 *
 * <p>This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
 */
public class FakeApiImpl implements FakeApi {

  private final ApiClient apiClient;

  protected static final GenericType<FakeBigDecimalMap200Response> RESPONSE_TYPE_fakeBigDecimalMap = ResponseType.create(FakeBigDecimalMap200Response.class);
  protected static final GenericType<HealthCheckResult> RESPONSE_TYPE_fakeHealthGet = ResponseType.create(HealthCheckResult.class);
  protected static final GenericType<Void> RESPONSE_TYPE_fakeHttpSignatureTest = ResponseType.create(Void.class);
  protected static final GenericType<Boolean> RESPONSE_TYPE_fakeOuterBooleanSerialize = ResponseType.create(Boolean.class);
  protected static final GenericType<OuterComposite> RESPONSE_TYPE_fakeOuterCompositeSerialize = ResponseType.create(OuterComposite.class);
  protected static final GenericType<BigDecimal> RESPONSE_TYPE_fakeOuterNumberSerialize = ResponseType.create(BigDecimal.class);
  protected static final GenericType<String> RESPONSE_TYPE_fakeOuterStringSerialize = ResponseType.create(String.class);
  protected static final GenericType<OuterObjectWithEnumProperty> RESPONSE_TYPE_fakePropertyEnumIntegerSerialize = ResponseType.create(OuterObjectWithEnumProperty.class);
  protected static final GenericType<Void> RESPONSE_TYPE_testBodyWithBinary = ResponseType.create(Void.class);
  protected static final GenericType<Void> RESPONSE_TYPE_testBodyWithFileSchema = ResponseType.create(Void.class);
  protected static final GenericType<Void> RESPONSE_TYPE_testBodyWithQueryParams = ResponseType.create(Void.class);
  protected static final GenericType<Client> RESPONSE_TYPE_testClientModel = ResponseType.create(Client.class);
  protected static final GenericType<Void> RESPONSE_TYPE_testEndpointParameters = ResponseType.create(Void.class);
  protected static final GenericType<Void> RESPONSE_TYPE_testEnumParameters = ResponseType.create(Void.class);
  protected static final GenericType<Void> RESPONSE_TYPE_testGroupParameters = ResponseType.create(Void.class);
  protected static final GenericType<Void> RESPONSE_TYPE_testInlineAdditionalProperties = ResponseType.create(Void.class);
  protected static final GenericType<Void> RESPONSE_TYPE_testJsonFormData = ResponseType.create(Void.class);
  protected static final GenericType<Void> RESPONSE_TYPE_testQueryParameterCollectionFormat = ResponseType.create(Void.class);

  /**
   * Creates a new instance of FakeApiImpl initialized with the specified {@link ApiClient}.
   *
   */
  public static FakeApiImpl create(ApiClient apiClient) {
    return new FakeApiImpl(apiClient);
  }

  protected FakeApiImpl(ApiClient apiClient) {
    this.apiClient = apiClient;
  }

  @Override
  public ApiResponse<FakeBigDecimalMap200Response> fakeBigDecimalMap() {
    WebClientRequestBuilder webClientRequestBuilder = fakeBigDecimalMapRequestBuilder();
    return fakeBigDecimalMapSubmit(webClientRequestBuilder);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the fakeBigDecimalMap operation.
   * Optional customization point for subclasses.
   *
   * @return WebClientRequestBuilder for fakeBigDecimalMap
   */
  protected WebClientRequestBuilder fakeBigDecimalMapRequestBuilder() {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("GET");

    webClientRequestBuilder.path("/fake/BigDecimalMap");
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the fakeBigDecimalMap operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @return {@code ApiResponse<FakeBigDecimalMap200Response>} for the submitted request
   */
  protected ApiResponse<FakeBigDecimalMap200Response> fakeBigDecimalMapSubmit(WebClientRequestBuilder webClientRequestBuilder) {
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit();
    return ApiResponse.create(RESPONSE_TYPE_fakeBigDecimalMap, webClientResponse);
  }

  @Override
  public ApiResponse<HealthCheckResult> fakeHealthGet() {
    WebClientRequestBuilder webClientRequestBuilder = fakeHealthGetRequestBuilder();
    return fakeHealthGetSubmit(webClientRequestBuilder);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the fakeHealthGet operation.
   * Optional customization point for subclasses.
   *
   * @return WebClientRequestBuilder for fakeHealthGet
   */
  protected WebClientRequestBuilder fakeHealthGetRequestBuilder() {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("GET");

    webClientRequestBuilder.path("/fake/health");
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the fakeHealthGet operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @return {@code ApiResponse<HealthCheckResult>} for the submitted request
   */
  protected ApiResponse<HealthCheckResult> fakeHealthGetSubmit(WebClientRequestBuilder webClientRequestBuilder) {
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit();
    return ApiResponse.create(RESPONSE_TYPE_fakeHealthGet, webClientResponse);
  }

  @Override
  public ApiResponse<Void> fakeHttpSignatureTest(Pet pet, String query1, String header1) {
    Objects.requireNonNull(pet, "Required parameter 'pet' not specified");
    WebClientRequestBuilder webClientRequestBuilder = fakeHttpSignatureTestRequestBuilder(pet, query1, header1);
    return fakeHttpSignatureTestSubmit(webClientRequestBuilder, pet, query1, header1);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the fakeHttpSignatureTest operation.
   * Optional customization point for subclasses.
   *
   * @param pet Pet object that needs to be added to the store (required)
   * @param query1 query parameter (optional)
   * @param header1 header parameter (optional)
   * @return WebClientRequestBuilder for fakeHttpSignatureTest
   */
  protected WebClientRequestBuilder fakeHttpSignatureTestRequestBuilder(Pet pet, String query1, String header1) {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("GET");

    List<Pair> queryParams = new ArrayList<>();
    queryParams.addAll(ApiClient.parameterToPairs("query_1", query1));
    queryParams.forEach(p -> webClientRequestBuilder.queryParam(p.getName(), p.getValue()));

    WebClientRequestHeaders headers = webClientRequestBuilder.headers();
    if (header1 != null) {
      headers.put("header_1", header1);
    }

    webClientRequestBuilder.path("/fake/http-signature-test");
    webClientRequestBuilder.contentType(MediaType.APPLICATION_JSON);
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the fakeHttpSignatureTest operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @param pet Pet object that needs to be added to the store (required)
   * @param query1 query parameter (optional)
   * @param header1 header parameter (optional)
   * @return {@code ApiResponse<Void>} for the submitted request
   */
  protected ApiResponse<Void> fakeHttpSignatureTestSubmit(WebClientRequestBuilder webClientRequestBuilder, Pet pet, String query1, String header1) {
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit(pet);
    return ApiResponse.create(RESPONSE_TYPE_fakeHttpSignatureTest, webClientResponse);
  }

  @Override
  public ApiResponse<Boolean> fakeOuterBooleanSerialize(Boolean body) {
    WebClientRequestBuilder webClientRequestBuilder = fakeOuterBooleanSerializeRequestBuilder(body);
    return fakeOuterBooleanSerializeSubmit(webClientRequestBuilder, body);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the fakeOuterBooleanSerialize operation.
   * Optional customization point for subclasses.
   *
   * @param body Input boolean as post body (optional)
   * @return WebClientRequestBuilder for fakeOuterBooleanSerialize
   */
  protected WebClientRequestBuilder fakeOuterBooleanSerializeRequestBuilder(Boolean body) {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("POST");

    webClientRequestBuilder.path("/fake/outer/boolean");
    webClientRequestBuilder.contentType(MediaType.APPLICATION_JSON);
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the fakeOuterBooleanSerialize operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @param body Input boolean as post body (optional)
   * @return {@code ApiResponse<Boolean>} for the submitted request
   */
  protected ApiResponse<Boolean> fakeOuterBooleanSerializeSubmit(WebClientRequestBuilder webClientRequestBuilder, Boolean body) {
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit(body);
    return ApiResponse.create(RESPONSE_TYPE_fakeOuterBooleanSerialize, webClientResponse);
  }

  @Override
  public ApiResponse<OuterComposite> fakeOuterCompositeSerialize(OuterComposite outerComposite) {
    WebClientRequestBuilder webClientRequestBuilder = fakeOuterCompositeSerializeRequestBuilder(outerComposite);
    return fakeOuterCompositeSerializeSubmit(webClientRequestBuilder, outerComposite);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the fakeOuterCompositeSerialize operation.
   * Optional customization point for subclasses.
   *
   * @param outerComposite Input composite as post body (optional)
   * @return WebClientRequestBuilder for fakeOuterCompositeSerialize
   */
  protected WebClientRequestBuilder fakeOuterCompositeSerializeRequestBuilder(OuterComposite outerComposite) {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("POST");

    webClientRequestBuilder.path("/fake/outer/composite");
    webClientRequestBuilder.contentType(MediaType.APPLICATION_JSON);
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the fakeOuterCompositeSerialize operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @param outerComposite Input composite as post body (optional)
   * @return {@code ApiResponse<OuterComposite>} for the submitted request
   */
  protected ApiResponse<OuterComposite> fakeOuterCompositeSerializeSubmit(WebClientRequestBuilder webClientRequestBuilder, OuterComposite outerComposite) {
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit(outerComposite);
    return ApiResponse.create(RESPONSE_TYPE_fakeOuterCompositeSerialize, webClientResponse);
  }

  @Override
  public ApiResponse<BigDecimal> fakeOuterNumberSerialize(BigDecimal body) {
    WebClientRequestBuilder webClientRequestBuilder = fakeOuterNumberSerializeRequestBuilder(body);
    return fakeOuterNumberSerializeSubmit(webClientRequestBuilder, body);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the fakeOuterNumberSerialize operation.
   * Optional customization point for subclasses.
   *
   * @param body Input number as post body (optional)
   * @return WebClientRequestBuilder for fakeOuterNumberSerialize
   */
  protected WebClientRequestBuilder fakeOuterNumberSerializeRequestBuilder(BigDecimal body) {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("POST");

    webClientRequestBuilder.path("/fake/outer/number");
    webClientRequestBuilder.contentType(MediaType.APPLICATION_JSON);
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the fakeOuterNumberSerialize operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @param body Input number as post body (optional)
   * @return {@code ApiResponse<BigDecimal>} for the submitted request
   */
  protected ApiResponse<BigDecimal> fakeOuterNumberSerializeSubmit(WebClientRequestBuilder webClientRequestBuilder, BigDecimal body) {
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit(body);
    return ApiResponse.create(RESPONSE_TYPE_fakeOuterNumberSerialize, webClientResponse);
  }

  @Override
  public ApiResponse<String> fakeOuterStringSerialize(String body) {
    WebClientRequestBuilder webClientRequestBuilder = fakeOuterStringSerializeRequestBuilder(body);
    return fakeOuterStringSerializeSubmit(webClientRequestBuilder, body);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the fakeOuterStringSerialize operation.
   * Optional customization point for subclasses.
   *
   * @param body Input string as post body (optional)
   * @return WebClientRequestBuilder for fakeOuterStringSerialize
   */
  protected WebClientRequestBuilder fakeOuterStringSerializeRequestBuilder(String body) {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("POST");

    webClientRequestBuilder.path("/fake/outer/string");
    webClientRequestBuilder.contentType(MediaType.APPLICATION_JSON);
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the fakeOuterStringSerialize operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @param body Input string as post body (optional)
   * @return {@code ApiResponse<String>} for the submitted request
   */
  protected ApiResponse<String> fakeOuterStringSerializeSubmit(WebClientRequestBuilder webClientRequestBuilder, String body) {
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit(body);
    return ApiResponse.create(RESPONSE_TYPE_fakeOuterStringSerialize, webClientResponse);
  }

  @Override
  public ApiResponse<OuterObjectWithEnumProperty> fakePropertyEnumIntegerSerialize(OuterObjectWithEnumProperty outerObjectWithEnumProperty) {
    Objects.requireNonNull(outerObjectWithEnumProperty, "Required parameter 'outerObjectWithEnumProperty' not specified");
    WebClientRequestBuilder webClientRequestBuilder = fakePropertyEnumIntegerSerializeRequestBuilder(outerObjectWithEnumProperty);
    return fakePropertyEnumIntegerSerializeSubmit(webClientRequestBuilder, outerObjectWithEnumProperty);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the fakePropertyEnumIntegerSerialize operation.
   * Optional customization point for subclasses.
   *
   * @param outerObjectWithEnumProperty Input enum (int) as post body (required)
   * @return WebClientRequestBuilder for fakePropertyEnumIntegerSerialize
   */
  protected WebClientRequestBuilder fakePropertyEnumIntegerSerializeRequestBuilder(OuterObjectWithEnumProperty outerObjectWithEnumProperty) {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("POST");

    webClientRequestBuilder.path("/fake/property/enum-int");
    webClientRequestBuilder.contentType(MediaType.APPLICATION_JSON);
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the fakePropertyEnumIntegerSerialize operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @param outerObjectWithEnumProperty Input enum (int) as post body (required)
   * @return {@code ApiResponse<OuterObjectWithEnumProperty>} for the submitted request
   */
  protected ApiResponse<OuterObjectWithEnumProperty> fakePropertyEnumIntegerSerializeSubmit(WebClientRequestBuilder webClientRequestBuilder, OuterObjectWithEnumProperty outerObjectWithEnumProperty) {
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit(outerObjectWithEnumProperty);
    return ApiResponse.create(RESPONSE_TYPE_fakePropertyEnumIntegerSerialize, webClientResponse);
  }

  @Override
  public ApiResponse<Void> testBodyWithBinary(File body) {
    Objects.requireNonNull(body, "Required parameter 'body' not specified");
    WebClientRequestBuilder webClientRequestBuilder = testBodyWithBinaryRequestBuilder(body);
    return testBodyWithBinarySubmit(webClientRequestBuilder, body);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the testBodyWithBinary operation.
   * Optional customization point for subclasses.
   *
   * @param body image to upload (required)
   * @return WebClientRequestBuilder for testBodyWithBinary
   */
  protected WebClientRequestBuilder testBodyWithBinaryRequestBuilder(File body) {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("PUT");

    webClientRequestBuilder.path("/fake/body-with-binary");
    webClientRequestBuilder.contentType(MediaType.APPLICATION_JSON);
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the testBodyWithBinary operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @param body image to upload (required)
   * @return {@code ApiResponse<Void>} for the submitted request
   */
  protected ApiResponse<Void> testBodyWithBinarySubmit(WebClientRequestBuilder webClientRequestBuilder, File body) {
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit(body);
    return ApiResponse.create(RESPONSE_TYPE_testBodyWithBinary, webClientResponse);
  }

  @Override
  public ApiResponse<Void> testBodyWithFileSchema(FileSchemaTestClass fileSchemaTestClass) {
    Objects.requireNonNull(fileSchemaTestClass, "Required parameter 'fileSchemaTestClass' not specified");
    WebClientRequestBuilder webClientRequestBuilder = testBodyWithFileSchemaRequestBuilder(fileSchemaTestClass);
    return testBodyWithFileSchemaSubmit(webClientRequestBuilder, fileSchemaTestClass);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the testBodyWithFileSchema operation.
   * Optional customization point for subclasses.
   *
   * @param fileSchemaTestClass  (required)
   * @return WebClientRequestBuilder for testBodyWithFileSchema
   */
  protected WebClientRequestBuilder testBodyWithFileSchemaRequestBuilder(FileSchemaTestClass fileSchemaTestClass) {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("PUT");

    webClientRequestBuilder.path("/fake/body-with-file-schema");
    webClientRequestBuilder.contentType(MediaType.APPLICATION_JSON);
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the testBodyWithFileSchema operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @param fileSchemaTestClass  (required)
   * @return {@code ApiResponse<Void>} for the submitted request
   */
  protected ApiResponse<Void> testBodyWithFileSchemaSubmit(WebClientRequestBuilder webClientRequestBuilder, FileSchemaTestClass fileSchemaTestClass) {
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit(fileSchemaTestClass);
    return ApiResponse.create(RESPONSE_TYPE_testBodyWithFileSchema, webClientResponse);
  }

  @Override
  public ApiResponse<Void> testBodyWithQueryParams(String query, User user) {
    Objects.requireNonNull(query, "Required parameter 'query' not specified");
    Objects.requireNonNull(user, "Required parameter 'user' not specified");
    WebClientRequestBuilder webClientRequestBuilder = testBodyWithQueryParamsRequestBuilder(query, user);
    return testBodyWithQueryParamsSubmit(webClientRequestBuilder, query, user);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the testBodyWithQueryParams operation.
   * Optional customization point for subclasses.
   *
   * @param query  (required)
   * @param user  (required)
   * @return WebClientRequestBuilder for testBodyWithQueryParams
   */
  protected WebClientRequestBuilder testBodyWithQueryParamsRequestBuilder(String query, User user) {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("PUT");

    List<Pair> queryParams = new ArrayList<>();
    queryParams.addAll(ApiClient.parameterToPairs("query", query));
    queryParams.forEach(p -> webClientRequestBuilder.queryParam(p.getName(), p.getValue()));

    webClientRequestBuilder.path("/fake/body-with-query-params");
    webClientRequestBuilder.contentType(MediaType.APPLICATION_JSON);
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the testBodyWithQueryParams operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @param query  (required)
   * @param user  (required)
   * @return {@code ApiResponse<Void>} for the submitted request
   */
  protected ApiResponse<Void> testBodyWithQueryParamsSubmit(WebClientRequestBuilder webClientRequestBuilder, String query, User user) {
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit(user);
    return ApiResponse.create(RESPONSE_TYPE_testBodyWithQueryParams, webClientResponse);
  }

  @Override
  public ApiResponse<Client> testClientModel(Client client) {
    Objects.requireNonNull(client, "Required parameter 'client' not specified");
    WebClientRequestBuilder webClientRequestBuilder = testClientModelRequestBuilder(client);
    return testClientModelSubmit(webClientRequestBuilder, client);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the testClientModel operation.
   * Optional customization point for subclasses.
   *
   * @param client client model (required)
   * @return WebClientRequestBuilder for testClientModel
   */
  protected WebClientRequestBuilder testClientModelRequestBuilder(Client client) {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("PATCH");

    webClientRequestBuilder.path("/fake");
    webClientRequestBuilder.contentType(MediaType.APPLICATION_JSON);
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the testClientModel operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @param client client model (required)
   * @return {@code ApiResponse<Client>} for the submitted request
   */
  protected ApiResponse<Client> testClientModelSubmit(WebClientRequestBuilder webClientRequestBuilder, Client client) {
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit(client);
    return ApiResponse.create(RESPONSE_TYPE_testClientModel, webClientResponse);
  }

  @Override
  public ApiResponse<Void> testEndpointParameters(BigDecimal number, Double _double, String patternWithoutDelimiter, byte[] _byte, Integer integer, Integer int32, Long int64, Float _float, String string, File binary, LocalDate date, OffsetDateTime dateTime, String password, String paramCallback) {
    Objects.requireNonNull(number, "Required parameter 'number' not specified");
    Objects.requireNonNull(_double, "Required parameter '_double' not specified");
    Objects.requireNonNull(patternWithoutDelimiter, "Required parameter 'patternWithoutDelimiter' not specified");
    Objects.requireNonNull(_byte, "Required parameter '_byte' not specified");
    WebClientRequestBuilder webClientRequestBuilder = testEndpointParametersRequestBuilder(number, _double, patternWithoutDelimiter, _byte, integer, int32, int64, _float, string, binary, date, dateTime, password, paramCallback);
    return testEndpointParametersSubmit(webClientRequestBuilder, number, _double, patternWithoutDelimiter, _byte, integer, int32, int64, _float, string, binary, date, dateTime, password, paramCallback);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the testEndpointParameters operation.
   * Optional customization point for subclasses.
   *
   * @param number None (required)
   * @param _double None (required)
   * @param patternWithoutDelimiter None (required)
   * @param _byte None (required)
   * @param integer None (optional)
   * @param int32 None (optional)
   * @param int64 None (optional)
   * @param _float None (optional)
   * @param string None (optional)
   * @param binary None (optional)
   * @param date None (optional)
   * @param dateTime None (optional)
   * @param password None (optional)
   * @param paramCallback None (optional)
   * @return WebClientRequestBuilder for testEndpointParameters
   */
  protected WebClientRequestBuilder testEndpointParametersRequestBuilder(BigDecimal number, Double _double, String patternWithoutDelimiter, byte[] _byte, Integer integer, Integer int32, Long int64, Float _float, String string, File binary, LocalDate date, OffsetDateTime dateTime, String password, String paramCallback) {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("POST");

    webClientRequestBuilder.path("/fake");
    webClientRequestBuilder.contentType(MediaType.APPLICATION_FORM_URLENCODED);
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the testEndpointParameters operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @param number None (required)
   * @param _double None (required)
   * @param patternWithoutDelimiter None (required)
   * @param _byte None (required)
   * @param integer None (optional)
   * @param int32 None (optional)
   * @param int64 None (optional)
   * @param _float None (optional)
   * @param string None (optional)
   * @param binary None (optional)
   * @param date None (optional)
   * @param dateTime None (optional)
   * @param password None (optional)
   * @param paramCallback None (optional)
   * @return {@code ApiResponse<Void>} for the submitted request
   */
  protected ApiResponse<Void> testEndpointParametersSubmit(WebClientRequestBuilder webClientRequestBuilder, BigDecimal number, Double _double, String patternWithoutDelimiter, byte[] _byte, Integer integer, Integer int32, Long int64, Float _float, String string, File binary, LocalDate date, OffsetDateTime dateTime, String password, String paramCallback) {
    String formParams = new StringJoiner("&")
            .add("integer=" + integer)
            .add("int32=" + int32)
            .add("int64=" + int64)
            .add("number=" + number)
            .add("float=" + _float)
            .add("double=" + _double)
            .add("string=" + string)
            .add("pattern_without_delimiter=" + patternWithoutDelimiter)
            .add("byte=" + _byte)
            .add("binary=" + binary)
            .add("date=" + date)
            .add("dateTime=" + dateTime)
            .add("password=" + password)
            .add("callback=" + paramCallback)
            .toString();
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit(formParams);
    return ApiResponse.create(RESPONSE_TYPE_testEndpointParameters, webClientResponse);
  }

  @Override
  public ApiResponse<Void> testEnumParameters(List<String> enumHeaderStringArray, String enumHeaderString, List<String> enumQueryStringArray, String enumQueryString, Integer enumQueryInteger, Double enumQueryDouble, List<EnumClass> enumQueryModelArray, List<String> enumFormStringArray, String enumFormString) {
    WebClientRequestBuilder webClientRequestBuilder = testEnumParametersRequestBuilder(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumQueryModelArray, enumFormStringArray, enumFormString);
    return testEnumParametersSubmit(webClientRequestBuilder, enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumQueryModelArray, enumFormStringArray, enumFormString);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the testEnumParameters operation.
   * Optional customization point for subclasses.
   *
   * @param enumHeaderStringArray Header parameter enum test (string array) (optional
   * @param enumHeaderString Header parameter enum test (string) (optional, default to -efg)
   * @param enumQueryStringArray Query parameter enum test (string array) (optional
   * @param enumQueryString Query parameter enum test (string) (optional, default to -efg)
   * @param enumQueryInteger Query parameter enum test (double) (optional)
   * @param enumQueryDouble Query parameter enum test (double) (optional)
   * @param enumQueryModelArray  (optional
   * @param enumFormStringArray Form parameter enum test (string array) (optional
   * @param enumFormString Form parameter enum test (string) (optional, default to -efg)
   * @return WebClientRequestBuilder for testEnumParameters
   */
  protected WebClientRequestBuilder testEnumParametersRequestBuilder(List<String> enumHeaderStringArray, String enumHeaderString, List<String> enumQueryStringArray, String enumQueryString, Integer enumQueryInteger, Double enumQueryDouble, List<EnumClass> enumQueryModelArray, List<String> enumFormStringArray, String enumFormString) {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("GET");

    List<Pair> queryParams = new ArrayList<>();
    queryParams.addAll(ApiClient.parameterToPairs("multi", "enum_query_string_array", enumQueryStringArray));
    queryParams.addAll(ApiClient.parameterToPairs("enum_query_string", enumQueryString));
    queryParams.addAll(ApiClient.parameterToPairs("enum_query_integer", enumQueryInteger));
    queryParams.addAll(ApiClient.parameterToPairs("enum_query_double", enumQueryDouble));
    queryParams.addAll(ApiClient.parameterToPairs("multi", "enum_query_model_array", enumQueryModelArray));
    queryParams.forEach(p -> webClientRequestBuilder.queryParam(p.getName(), p.getValue()));

    WebClientRequestHeaders headers = webClientRequestBuilder.headers();
    if (enumHeaderStringArray != null) {
      headers.put("enum_header_string_array", enumHeaderStringArray.toString());
    }
    if (enumHeaderString != null) {
      headers.put("enum_header_string", enumHeaderString);
    }

    webClientRequestBuilder.path("/fake");
    webClientRequestBuilder.contentType(MediaType.APPLICATION_FORM_URLENCODED);
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the testEnumParameters operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @param enumHeaderStringArray Header parameter enum test (string array) (optional
   * @param enumHeaderString Header parameter enum test (string) (optional, default to -efg)
   * @param enumQueryStringArray Query parameter enum test (string array) (optional
   * @param enumQueryString Query parameter enum test (string) (optional, default to -efg)
   * @param enumQueryInteger Query parameter enum test (double) (optional)
   * @param enumQueryDouble Query parameter enum test (double) (optional)
   * @param enumQueryModelArray  (optional
   * @param enumFormStringArray Form parameter enum test (string array) (optional
   * @param enumFormString Form parameter enum test (string) (optional, default to -efg)
   * @return {@code ApiResponse<Void>} for the submitted request
   */
  protected ApiResponse<Void> testEnumParametersSubmit(WebClientRequestBuilder webClientRequestBuilder, List<String> enumHeaderStringArray, String enumHeaderString, List<String> enumQueryStringArray, String enumQueryString, Integer enumQueryInteger, Double enumQueryDouble, List<EnumClass> enumQueryModelArray, List<String> enumFormStringArray, String enumFormString) {
    String formParams = new StringJoiner("&")
            .add("enum_form_string_array=" + enumFormStringArray)
            .add("enum_form_string=" + enumFormString)
            .toString();
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit(formParams);
    return ApiResponse.create(RESPONSE_TYPE_testEnumParameters, webClientResponse);
  }

  @Override
  public ApiResponse<Void> testGroupParameters(Integer requiredStringGroup, Boolean requiredBooleanGroup, Long requiredInt64Group, Integer stringGroup, Boolean booleanGroup, Long int64Group) {
    Objects.requireNonNull(requiredStringGroup, "Required parameter 'requiredStringGroup' not specified");
    Objects.requireNonNull(requiredBooleanGroup, "Required parameter 'requiredBooleanGroup' not specified");
    Objects.requireNonNull(requiredInt64Group, "Required parameter 'requiredInt64Group' not specified");
    WebClientRequestBuilder webClientRequestBuilder = testGroupParametersRequestBuilder(requiredStringGroup, requiredBooleanGroup, requiredInt64Group, stringGroup, booleanGroup, int64Group);
    return testGroupParametersSubmit(webClientRequestBuilder, requiredStringGroup, requiredBooleanGroup, requiredInt64Group, stringGroup, booleanGroup, int64Group);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the testGroupParameters operation.
   * Optional customization point for subclasses.
   *
   * @param requiredStringGroup Required String in group parameters (required)
   * @param requiredBooleanGroup Required Boolean in group parameters (required)
   * @param requiredInt64Group Required Integer in group parameters (required)
   * @param stringGroup String in group parameters (optional)
   * @param booleanGroup Boolean in group parameters (optional)
   * @param int64Group Integer in group parameters (optional)
   * @return WebClientRequestBuilder for testGroupParameters
   */
  protected WebClientRequestBuilder testGroupParametersRequestBuilder(Integer requiredStringGroup, Boolean requiredBooleanGroup, Long requiredInt64Group, Integer stringGroup, Boolean booleanGroup, Long int64Group) {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("DELETE");

    List<Pair> queryParams = new ArrayList<>();
    queryParams.addAll(ApiClient.parameterToPairs("required_string_group", requiredStringGroup));
    queryParams.addAll(ApiClient.parameterToPairs("required_int64_group", requiredInt64Group));
    queryParams.addAll(ApiClient.parameterToPairs("string_group", stringGroup));
    queryParams.addAll(ApiClient.parameterToPairs("int64_group", int64Group));
    queryParams.forEach(p -> webClientRequestBuilder.queryParam(p.getName(), p.getValue()));

    WebClientRequestHeaders headers = webClientRequestBuilder.headers();
    if (requiredBooleanGroup != null) {
      headers.put("required_boolean_group", requiredBooleanGroup.toString());
    }
    if (booleanGroup != null) {
      headers.put("boolean_group", booleanGroup.toString());
    }

    webClientRequestBuilder.path("/fake");
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the testGroupParameters operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @param requiredStringGroup Required String in group parameters (required)
   * @param requiredBooleanGroup Required Boolean in group parameters (required)
   * @param requiredInt64Group Required Integer in group parameters (required)
   * @param stringGroup String in group parameters (optional)
   * @param booleanGroup Boolean in group parameters (optional)
   * @param int64Group Integer in group parameters (optional)
   * @return {@code ApiResponse<Void>} for the submitted request
   */
  protected ApiResponse<Void> testGroupParametersSubmit(WebClientRequestBuilder webClientRequestBuilder, Integer requiredStringGroup, Boolean requiredBooleanGroup, Long requiredInt64Group, Integer stringGroup, Boolean booleanGroup, Long int64Group) {
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit();
    return ApiResponse.create(RESPONSE_TYPE_testGroupParameters, webClientResponse);
  }

  @Override
  public ApiResponse<Void> testInlineAdditionalProperties(Map<String, String> requestBody) {
    Objects.requireNonNull(requestBody, "Required parameter 'requestBody' not specified");
    WebClientRequestBuilder webClientRequestBuilder = testInlineAdditionalPropertiesRequestBuilder(requestBody);
    return testInlineAdditionalPropertiesSubmit(webClientRequestBuilder, requestBody);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the testInlineAdditionalProperties operation.
   * Optional customization point for subclasses.
   *
   * @param requestBody request body (required)
   * @return WebClientRequestBuilder for testInlineAdditionalProperties
   */
  protected WebClientRequestBuilder testInlineAdditionalPropertiesRequestBuilder(Map<String, String> requestBody) {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("POST");

    webClientRequestBuilder.path("/fake/inline-additionalProperties");
    webClientRequestBuilder.contentType(MediaType.APPLICATION_JSON);
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the testInlineAdditionalProperties operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @param requestBody request body (required)
   * @return {@code ApiResponse<Void>} for the submitted request
   */
  protected ApiResponse<Void> testInlineAdditionalPropertiesSubmit(WebClientRequestBuilder webClientRequestBuilder, Map<String, String> requestBody) {
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit(requestBody);
    return ApiResponse.create(RESPONSE_TYPE_testInlineAdditionalProperties, webClientResponse);
  }

  @Override
  public ApiResponse<Void> testJsonFormData(String param, String param2) {
    Objects.requireNonNull(param, "Required parameter 'param' not specified");
    Objects.requireNonNull(param2, "Required parameter 'param2' not specified");
    WebClientRequestBuilder webClientRequestBuilder = testJsonFormDataRequestBuilder(param, param2);
    return testJsonFormDataSubmit(webClientRequestBuilder, param, param2);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the testJsonFormData operation.
   * Optional customization point for subclasses.
   *
   * @param param field1 (required)
   * @param param2 field2 (required)
   * @return WebClientRequestBuilder for testJsonFormData
   */
  protected WebClientRequestBuilder testJsonFormDataRequestBuilder(String param, String param2) {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("GET");

    webClientRequestBuilder.path("/fake/jsonFormData");
    webClientRequestBuilder.contentType(MediaType.APPLICATION_FORM_URLENCODED);
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the testJsonFormData operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @param param field1 (required)
   * @param param2 field2 (required)
   * @return {@code ApiResponse<Void>} for the submitted request
   */
  protected ApiResponse<Void> testJsonFormDataSubmit(WebClientRequestBuilder webClientRequestBuilder, String param, String param2) {
    String formParams = new StringJoiner("&")
            .add("param=" + param)
            .add("param2=" + param2)
            .toString();
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit(formParams);
    return ApiResponse.create(RESPONSE_TYPE_testJsonFormData, webClientResponse);
  }

  @Override
  public ApiResponse<Void> testQueryParameterCollectionFormat(List<String> pipe, List<String> ioutil, List<String> http, List<String> url, List<String> context, String allowEmpty, Map<String, String> language) {
    Objects.requireNonNull(pipe, "Required parameter 'pipe' not specified");
    Objects.requireNonNull(ioutil, "Required parameter 'ioutil' not specified");
    Objects.requireNonNull(http, "Required parameter 'http' not specified");
    Objects.requireNonNull(url, "Required parameter 'url' not specified");
    Objects.requireNonNull(context, "Required parameter 'context' not specified");
    Objects.requireNonNull(allowEmpty, "Required parameter 'allowEmpty' not specified");
    WebClientRequestBuilder webClientRequestBuilder = testQueryParameterCollectionFormatRequestBuilder(pipe, ioutil, http, url, context, allowEmpty, language);
    return testQueryParameterCollectionFormatSubmit(webClientRequestBuilder, pipe, ioutil, http, url, context, allowEmpty, language);
  }

  /**
   * Creates a {@code WebClientRequestBuilder} for the testQueryParameterCollectionFormat operation.
   * Optional customization point for subclasses.
   *
   * @param pipe  (required)
   * @param ioutil  (required)
   * @param http  (required)
   * @param url  (required)
   * @param context  (required)
   * @param allowEmpty  (required)
   * @param language  (optional
   * @return WebClientRequestBuilder for testQueryParameterCollectionFormat
   */
  protected WebClientRequestBuilder testQueryParameterCollectionFormatRequestBuilder(List<String> pipe, List<String> ioutil, List<String> http, List<String> url, List<String> context, String allowEmpty, Map<String, String> language) {
    WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
            .method("PUT");

    List<Pair> queryParams = new ArrayList<>();
    queryParams.addAll(ApiClient.parameterToPairs("pipes", "pipe", pipe));
    queryParams.addAll(ApiClient.parameterToPairs("csv", "ioutil", ioutil));
    queryParams.addAll(ApiClient.parameterToPairs("ssv", "http", http));
    queryParams.addAll(ApiClient.parameterToPairs("csv", "url", url));
    queryParams.addAll(ApiClient.parameterToPairs("multi", "context", context));
    queryParams.addAll(ApiClient.parameterToPairs("language", language));
    queryParams.addAll(ApiClient.parameterToPairs("allowEmpty", allowEmpty));
    queryParams.forEach(p -> webClientRequestBuilder.queryParam(p.getName(), p.getValue()));

    webClientRequestBuilder.path("/fake/test-query-parameters");
    webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);

    return webClientRequestBuilder;
  }

  /**
   * Initiates the request for the testQueryParameterCollectionFormat operation.
   * Optional customization point for subclasses.
   *
   * @param webClientRequestBuilder the request builder to use for submitting the request
   * @param pipe  (required)
   * @param ioutil  (required)
   * @param http  (required)
   * @param url  (required)
   * @param context  (required)
   * @param allowEmpty  (required)
   * @param language  (optional
   * @return {@code ApiResponse<Void>} for the submitted request
   */
  protected ApiResponse<Void> testQueryParameterCollectionFormatSubmit(WebClientRequestBuilder webClientRequestBuilder, List<String> pipe, List<String> ioutil, List<String> http, List<String> url, List<String> context, String allowEmpty, Map<String, String> language) {
    Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit();
    return ApiResponse.create(RESPONSE_TYPE_testQueryParameterCollectionFormat, webClientResponse);
  }

}
