// This file was auto-generated by Fern from our API Definition.

import { BearerAuthProvider } from "./auth/BearerAuthProvider.js";
import { mergeHeaders } from "./core/headers.js";
import * as core from "./core/index.js";
import type * as environments from "./environments.js";

export type BaseClientOptions = {
    environment?: core.Supplier<environments.LatitudeApiEnvironment | string>;
    /** Specify a custom URL to connect the client to. */
    baseUrl?: core.Supplier<string>;
    /** Additional headers to include in requests. */
    headers?: Record<string, string | core.Supplier<string | null | undefined> | null | undefined>;
    /** The default maximum time to wait for a response in seconds. */
    timeoutInSeconds?: number;
    /** The default number of times to retry the request. Defaults to 2. */
    maxRetries?: number;
    /** Provide a custom fetch implementation. Useful for platforms that don't have a built-in fetch or need a custom implementation. */
    fetch?: typeof fetch;
    /** Configure logging for the client. */
    logging?: core.logging.LogConfig | core.logging.Logger;
} & BearerAuthProvider.AuthOptions;

export interface BaseRequestOptions {
    /** The maximum time to wait for a response in seconds. */
    timeoutInSeconds?: number;
    /** The number of times to retry the request. Defaults to 2. */
    maxRetries?: number;
    /** A hook to abort the request. */
    abortSignal?: AbortSignal;
    /** Additional query string parameters to include in the request. */
    queryParams?: Record<string, unknown>;
    /** Additional headers to include in the request. */
    headers?: Record<string, string | core.Supplier<string | null | undefined> | null | undefined>;
}

export type NormalizedClientOptions<T extends BaseClientOptions = BaseClientOptions> = T & {
    logging: core.logging.Logger;
    authProvider?: core.AuthProvider;
};

export type NormalizedClientOptionsWithAuth<T extends BaseClientOptions = BaseClientOptions> =
    NormalizedClientOptions<T> & {
        authProvider: core.AuthProvider;
    };

export function normalizeClientOptions<T extends BaseClientOptions = BaseClientOptions>(
    options: T,
): NormalizedClientOptions<T> {
    const headers = mergeHeaders(
        {
            "X-Fern-Language": "JavaScript",
            "X-Fern-Runtime": core.RUNTIME.type,
            "X-Fern-Runtime-Version": core.RUNTIME.version,
        },
        options?.headers,
    );

    return {
        ...options,
        logging: core.logging.createLogger(options?.logging),
        headers,
    } as NormalizedClientOptions<T>;
}

export function normalizeClientOptionsWithAuth<T extends BaseClientOptions = BaseClientOptions>(
    options: T,
): NormalizedClientOptionsWithAuth<T> {
    const normalized = normalizeClientOptions(options) as NormalizedClientOptionsWithAuth<T>;
    const normalizedWithNoOpAuthProvider = withNoOpAuthProvider(normalized);
    normalized.authProvider ??= new BearerAuthProvider(normalizedWithNoOpAuthProvider);
    return normalized;
}

function withNoOpAuthProvider<T extends BaseClientOptions = BaseClientOptions>(
    options: NormalizedClientOptions<T>,
): NormalizedClientOptionsWithAuth<T> {
    return {
        ...options,
        authProvider: new core.NoOpAuthProvider(),
    };
}
