/*
 * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
 * @generated-id: fac8da972f86
 */

export type APICall =
  | {
      status: "complete";
      request: Request;
      response: Response;
    }
  | {
      status: "request-error";
      request: Request;
      response?: undefined;
    }
  | {
      status: "invalid";
      request?: undefined;
      response?: undefined;
    };

export class APIPromise<T> implements Promise<T> {
  readonly #promise: Promise<[T, APICall]>;
  #unwrapped: Promise<T> | null;

  readonly [Symbol.toStringTag] = "APIPromise";

  constructor(p: [T, APICall] | Promise<[T, APICall]>) {
    this.#promise = p instanceof Promise ? p : Promise.resolve(p);
    this.#unwrapped = p instanceof Promise ? null : Promise.resolve(p[0]);
  }

  #getUnwrapped(): Promise<T> {
    return (this.#unwrapped ??= this.#promise.then(([value]) => value));
  }

  then<TResult1 = T, TResult2 = never>(
    onfulfilled?:
      | ((value: T) => TResult1 | PromiseLike<TResult1>)
      | null
      | undefined,
    onrejected?:
      | ((reason: any) => TResult2 | PromiseLike<TResult2>)
      | null
      | undefined,
  ): Promise<TResult1 | TResult2> {
    return this.#promise.then(
      onfulfilled ? ([value]) => onfulfilled(value) : void 0,
      onrejected,
    );
  }

  catch<TResult = never>(
    onrejected?:
      | ((reason: any) => TResult | PromiseLike<TResult>)
      | null
      | undefined,
  ): Promise<T | TResult> {
    return this.#getUnwrapped().catch(onrejected);
  }

  finally(onfinally?: (() => void) | null | undefined): Promise<T> {
    return this.#getUnwrapped().finally(onfinally);
  }

  $inspect(): Promise<[T, APICall]> {
    return this.#promise;
  }
}
