// Generated by smithplates HTTP codegen. Do not edit.

import { dumpApiModel } from "generated/example/authApi/modelValidation";
import { parseClientResponse } from "generated/example/authApi/client/clientResponse";
import { OPERATION_HTTP_BINDINGS } from "generated/example/authApi/client/operationBindings";
import type { AuthProvider } from "generated/example/authApi/client/operationBindings";
import { OPERATION_AUTH_BINDINGS, applyOperationAuth } from "generated/example/authApi/client/operationBindings";
import type { AuthOutput } from "generated/example/authOutput";

function encodeRfc3986(value: string): string {
  return encodeURIComponent(value).replace(
    /[!'()*]/g,
    (character) => "%" + character.charCodeAt(0).toString(16).toUpperCase(),
  );
}

export class AuthApiClient {
  private readonly baseUrl: string;
  private readonly fetchFn: typeof fetch;
  private readonly authProvider: AuthProvider | undefined;

  constructor(baseUrl: string, fetchFn: typeof fetch = fetch, authProvider?: AuthProvider) {
    this.baseUrl = baseUrl.replace(/\/+$/, "");
    this.fetchFn = fetchFn;
    this.authProvider = authProvider;
  }

  async apiKeyOnly(
  ): Promise<AuthOutput> {
    const headers: Record<string, string> = {};
    const queryParts: string[] = [];
    applyOperationAuth(
      OPERATION_AUTH_BINDINGS["apiKeyOnly"],
      this.authProvider,
      headers,
      queryParts,
    );
    const queryString = queryParts.join("&");
    const requestUrl = `${this.baseUrl}/api-key` + (queryString ? "?" + queryString : "");
    const response = await this.fetchFn(
      requestUrl,
      {
        method: "GET",
        headers,
      },
    );
    const normalized = {
      status: response.status,
      headers: Object.fromEntries(response.headers.entries()),
      text: () => response.text(),
      json: async () => await response.json(),
    };
    const parsed = await parseClientResponse(normalized, OPERATION_HTTP_BINDINGS["apiKeyOnly"]);
    return parsed as AuthOutput;
  }

  async bearerOnly(
  ): Promise<AuthOutput> {
    const headers: Record<string, string> = {};
    const queryParts: string[] = [];
    applyOperationAuth(
      OPERATION_AUTH_BINDINGS["bearerOnly"],
      this.authProvider,
      headers,
      queryParts,
    );
    const queryString = queryParts.join("&");
    const requestUrl = `${this.baseUrl}/bearer` + (queryString ? "?" + queryString : "");
    const response = await this.fetchFn(
      requestUrl,
      {
        method: "GET",
        headers,
      },
    );
    const normalized = {
      status: response.status,
      headers: Object.fromEntries(response.headers.entries()),
      text: () => response.text(),
      json: async () => await response.json(),
    };
    const parsed = await parseClientResponse(normalized, OPERATION_HTTP_BINDINGS["bearerOnly"]);
    return parsed as AuthOutput;
  }

  async cookieOnly(
  ): Promise<AuthOutput> {
    const headers: Record<string, string> = {};
    const queryParts: string[] = [];
    applyOperationAuth(
      OPERATION_AUTH_BINDINGS["cookieOnly"],
      this.authProvider,
      headers,
      queryParts,
    );
    const queryString = queryParts.join("&");
    const requestUrl = `${this.baseUrl}/cookie` + (queryString ? "?" + queryString : "");
    const response = await this.fetchFn(
      requestUrl,
      {
        method: "GET",
        headers,
        credentials: "include",
      },
    );
    const normalized = {
      status: response.status,
      headers: Object.fromEntries(response.headers.entries()),
      text: () => response.text(),
      json: async () => await response.json(),
    };
    const parsed = await parseClientResponse(normalized, OPERATION_HTTP_BINDINGS["cookieOnly"]);
    return parsed as AuthOutput;
  }

  async optional(
  ): Promise<AuthOutput> {
    const headers: Record<string, string> = {};
    const queryParts: string[] = [];
    applyOperationAuth(
      OPERATION_AUTH_BINDINGS["optional"],
      this.authProvider,
      headers,
      queryParts,
    );
    const queryString = queryParts.join("&");
    const requestUrl = `${this.baseUrl}/optional` + (queryString ? "?" + queryString : "");
    const response = await this.fetchFn(
      requestUrl,
      {
        method: "GET",
        headers,
        credentials: "include",
      },
    );
    const normalized = {
      status: response.status,
      headers: Object.fromEntries(response.headers.entries()),
      text: () => response.text(),
      json: async () => await response.json(),
    };
    const parsed = await parseClientResponse(normalized, OPERATION_HTTP_BINDINGS["optional"]);
    return parsed as AuthOutput;
  }

  async public_(
  ): Promise<AuthOutput> {
    const headers: Record<string, string> = {};
    const queryParts: string[] = [];
    const queryString = queryParts.join("&");
    const requestUrl = `${this.baseUrl}/public` + (queryString ? "?" + queryString : "");
    const response = await this.fetchFn(
      requestUrl,
      {
        method: "GET",
        headers,
      },
    );
    const normalized = {
      status: response.status,
      headers: Object.fromEntries(response.headers.entries()),
      text: () => response.text(),
      json: async () => await response.json(),
    };
    const parsed = await parseClientResponse(normalized, OPERATION_HTTP_BINDINGS["public_"]);
    return parsed as AuthOutput;
  }

  async required(
    trace: string | null,
    filter: string | null,
  ): Promise<AuthOutput> {
    const headers: Record<string, string> = {};
    if (trace !== null && trace !== undefined) {
      headers["X-Trace"] = String(trace);
    }
    const queryParts: string[] = [];
    if (filter !== null && filter !== undefined) {
      queryParts.push(encodeRfc3986("filter") + "=" + encodeRfc3986(String(filter)));
    }
    applyOperationAuth(
      OPERATION_AUTH_BINDINGS["required"],
      this.authProvider,
      headers,
      queryParts,
    );
    const queryString = queryParts.join("&");
    const requestUrl = `${this.baseUrl}/required` + (queryString ? "?" + queryString : "");
    const response = await this.fetchFn(
      requestUrl,
      {
        method: "GET",
        headers,
        credentials: "include",
      },
    );
    const normalized = {
      status: response.status,
      headers: Object.fromEntries(response.headers.entries()),
      text: () => response.text(),
      json: async () => await response.json(),
    };
    const parsed = await parseClientResponse(normalized, OPERATION_HTTP_BINDINGS["required"]);
    return parsed as AuthOutput;
  }
}
