// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

import { APIResource } from '../../resource';
import { isRequestOptions } from '../../core';
import * as Core from '../../core';
import * as DownloadsAPI from './downloads';
import { Downloads } from './downloads';
import * as LogsAPI from './logs';
import { LogListResponse, Logs, SessionLog } from './logs';
import * as ReplaysAPI from './replays';
import { ReplayRetrieveResponse, Replays } from './replays';
import * as UploadsAPI from './uploads';
import { UploadCreateParams, UploadCreateResponse, Uploads } from './uploads';
import * as RecordingAPI from './recording/recording';
import { Recording, RecordingRetrieveResponse, SessionRecording } from './recording/recording';

export class Sessions extends APIResource {
  downloads: DownloadsAPI.Downloads = new DownloadsAPI.Downloads(this._client);
  logs: LogsAPI.Logs = new LogsAPI.Logs(this._client);
  recording: RecordingAPI.Recording = new RecordingAPI.Recording(this._client);
  uploads: UploadsAPI.Uploads = new UploadsAPI.Uploads(this._client);
  replays: ReplaysAPI.Replays = new ReplaysAPI.Replays(this._client);

  /**
   * Create a Session
   */
  create(params?: SessionCreateParams, options?: Core.RequestOptions): Core.APIPromise<SessionCreateResponse>;
  create(options?: Core.RequestOptions): Core.APIPromise<SessionCreateResponse>;
  create(
    params: SessionCreateParams | Core.RequestOptions = {},
    options?: Core.RequestOptions,
  ): Core.APIPromise<SessionCreateResponse> {
    if (isRequestOptions(params)) {
      return this.create({}, params);
    }
    const { api_timeout, ...body } = params;
    return this._client.post('/v1/sessions', { body: { timeout: api_timeout, ...body }, ...options });
  }

  /**
   * Get a Session
   */
  retrieve(id: string, options?: Core.RequestOptions): Core.APIPromise<SessionRetrieveResponse> {
    return this._client.get(`/v1/sessions/${id}`, options);
  }

  /**
   * Update a Session
   */
  update(id: string, body: SessionUpdateParams, options?: Core.RequestOptions): Core.APIPromise<Session> {
    return this._client.post(`/v1/sessions/${id}`, { body, ...options });
  }

  /**
   * List Sessions
   */
  list(query?: SessionListParams, options?: Core.RequestOptions): Core.APIPromise<SessionListResponse>;
  list(options?: Core.RequestOptions): Core.APIPromise<SessionListResponse>;
  list(
    query: SessionListParams | Core.RequestOptions = {},
    options?: Core.RequestOptions,
  ): Core.APIPromise<SessionListResponse> {
    if (isRequestOptions(query)) {
      return this.list({}, query);
    }
    return this._client.get('/v1/sessions', { query, ...options });
  }

  /**
   * Session Live URLs
   */
  debug(
    id: string,
    query?: SessionDebugParams,
    options?: Core.RequestOptions,
  ): Core.APIPromise<SessionLiveURLs>;
  debug(id: string, options?: Core.RequestOptions): Core.APIPromise<SessionLiveURLs>;
  debug(
    id: string,
    query: SessionDebugParams | Core.RequestOptions = {},
    options?: Core.RequestOptions,
  ): Core.APIPromise<SessionLiveURLs> {
    if (isRequestOptions(query)) {
      return this.debug(id, {}, query);
    }
    return this._client.get(`/v1/sessions/${id}/debug`, { query, ...options });
  }
}

export interface Session {
  id: string;

  createdAt: string;

  expiresAt: string;

  /**
   * Indicates if the Session was created to be kept alive upon disconnections
   */
  keepAlive: boolean;

  /**
   * The Project ID linked to the Session.
   */
  projectId: string;

  /**
   * Bytes used via the [Proxy](/features/stealth-mode#proxies-and-residential-ips)
   */
  proxyBytes: number;

  /**
   * The region where the Session is running.
   */
  region: 'us-west-2' | 'us-east-1' | 'eu-central-1' | 'ap-southeast-1';

  startedAt: string;

  status: 'PENDING' | 'RUNNING' | 'ERROR' | 'TIMED_OUT' | 'COMPLETED';

  updatedAt: string;

  /**
   * Optional. The Context linked to the Session.
   */
  contextId?: string;

  endedAt?: string;

  /**
   * Arbitrary user metadata to attach to the session. To learn more about user
   * metadata, see [User Metadata](/features/sessions#user-metadata).
   */
  userMetadata?: { [key: string]: unknown };
}

export interface SessionLiveURLs {
  debuggerFullscreenUrl: string;

  debuggerUrl: string;

  pages: Array<SessionLiveURLs.Page>;

  wsUrl: string;
}

export namespace SessionLiveURLs {
  export interface Page {
    id: string;

    debuggerFullscreenUrl: string;

    debuggerUrl: string;

    faviconUrl: string;

    title: string;

    url: string;
  }
}

export interface SessionCreateResponse extends Session {
  /**
   * WebSocket URL to connect to the Session.
   */
  connectUrl: string;

  /**
   * HTTP URL to connect to the Session.
   */
  seleniumRemoteUrl: string;

  /**
   * Signing key to use when connecting to the Session via HTTP.
   */
  signingKey: string;
}

export interface SessionRetrieveResponse extends Session {
  /**
   * WebSocket URL to connect to the Session.
   */
  connectUrl?: string;

  /**
   * HTTP URL to connect to the Session.
   */
  seleniumRemoteUrl?: string;

  /**
   * Signing key to use when connecting to the Session via HTTP.
   */
  signingKey?: string;
}

export type SessionListResponse = Array<Session>;

export interface SessionCreateParams {
  browserSettings?: SessionCreateParams.BrowserSettings;

  /**
   * The uploaded Extension ID. See
   * [Upload Extension](/reference/api/upload-an-extension).
   */
  extensionId?: string;

  /**
   * Set to true to keep the session alive even after disconnections. Available on
   * the Hobby Plan and above.
   */
  keepAlive?: boolean;

  /**
   * The Project ID. Can be found in
   * [Settings](https://www.browserbase.com/settings). Optional - if not provided,
   * the project will be inferred from the API key.
   */
  projectId?: string;

  /**
   * Proxy configuration. Can be true for default proxy, or an array of proxy
   * configurations.
   */
  proxies?:
    | Array<
        | SessionCreateParams.BrowserbaseProxyConfig
        | SessionCreateParams.ExternalProxyConfig
        | SessionCreateParams.NoneProxyConfig
      >
    | boolean;

  /**
   * Supplementary proxy settings. Optional.
   */
  proxySettings?: SessionCreateParams.ProxySettings;

  /**
   * The region where the Session should run.
   */
  region?: 'us-west-2' | 'us-east-1' | 'eu-central-1' | 'ap-southeast-1';

  /**
   * Duration in seconds after which the session will automatically end. Defaults to
   * the Project's `defaultTimeout`. Minimum 60 seconds, maximum 21600 seconds (6
   * hours).
   */
  api_timeout?: number;

  /**
   * Arbitrary user metadata to attach to the session. To learn more about user
   * metadata, see [User Metadata](/features/sessions#user-metadata).
   */
  userMetadata?: { [key: string]: unknown };
}

export namespace SessionCreateParams {
  export interface BrowserSettings {
    /**
     * @deprecated Advanced Browser Stealth Mode. Deprecated: use `verified` instead.
     */
    advancedStealth?: boolean;

    /**
     * An optional list of allowed domains for the session. If you pass one or more
     * domains, Browserbase restricts top-level (main-frame) page navigations to the
     * listed domains and their subdomains. For example, `example.com` also permits
     * `www.example.com` and `a.b.example.com`, but not `notexample.com`. Matching is
     * domain-based, not full-URL. An empty list (the default) disables the restriction
     * entirely. Browserbase enforces only main-frame navigations; it does not block
     * iframe/subframe loads or other in-page resource requests (images, scripts, XHR,
     * etc.).
     */
    allowedDomains?: Array<string>;

    /**
     * Enable or disable ad blocking in the browser. Defaults to `false`.
     */
    blockAds?: boolean;

    /**
     * Custom selector for captcha image. See
     * [Custom Captcha Solving](/features/stealth-mode#custom-captcha-solving)
     */
    captchaImageSelector?: string;

    /**
     * Custom selector for captcha input. See
     * [Custom Captcha Solving](/features/stealth-mode#custom-captcha-solving)
     */
    captchaInputSelector?: string;

    context?: BrowserSettings.Context;

    /**
     * The uploaded Extension ID. See
     * [Upload Extension](/reference/api/upload-an-extension).
     */
    extensionId?: string;

    /**
     * Enable or disable ignoring of certificate errors in the browser. Defaults to
     * `false`, so TLS certificate validation is enforced; set to `true` to ignore
     * certificate errors (for example, to reach hosts with expired or self-signed
     * certificates).
     */
    ignoreCertificateErrors?: boolean;

    /**
     * Enable or disable session logging. Defaults to `true`.
     */
    logSession?: boolean;

    /**
     * Operating system for stealth mode. Valid values: windows, mac, linux, mobile,
     * tablet
     */
    os?: 'windows' | 'mac' | 'linux' | 'mobile' | 'tablet';

    /**
     * Enable or disable session recording. Defaults to `true`.
     */
    recordSession?: boolean;

    /**
     * Enable or disable captcha solving in the browser. Defaults to `true`.
     */
    solveCaptchas?: boolean;

    /**
     * Verified Browser Mode
     */
    verified?: boolean;

    viewport?: BrowserSettings.Viewport;
  }

  export namespace BrowserSettings {
    export interface Context {
      /**
       * The Context ID.
       */
      id: string;

      /**
       * Whether or not to persist the context after browsing. Defaults to `false`.
       */
      persist?: boolean;
    }

    export interface Viewport {
      /**
       * The height of the browser.
       */
      height?: number;

      /**
       * The width of the browser.
       */
      width?: number;
    }
  }

  export interface BrowserbaseProxyConfig {
    /**
     * Type of proxy. Always use 'browserbase' for the Browserbase managed proxy
     * network.
     */
    type: 'browserbase';

    /**
     * Domain pattern for which this proxy should be used. If omitted, defaults to all
     * domains. Optional.
     */
    domainPattern?: string;

    /**
     * Geographic location for the proxy. Optional.
     */
    geolocation?: BrowserbaseProxyConfig.Geolocation;
  }

  export namespace BrowserbaseProxyConfig {
    /**
     * Geographic location for the proxy. Optional.
     */
    export interface Geolocation {
      /**
       * Country code in ISO 3166-1 alpha-2 format
       */
      country: string;

      /**
       * Name of the city. Use spaces for multi-word city names. Optional.
       */
      city?: string;

      /**
       * US state code (2 characters). Must also specify US as the country. Optional.
       */
      state?: string;
    }
  }

  export interface ExternalProxyConfig {
    /**
     * Server URL for external proxy. Required.
     */
    server: string;

    /**
     * Type of proxy. Always 'external' for this config.
     */
    type: 'external';

    /**
     * Domain pattern for which this proxy should be used. If omitted, defaults to all
     * domains. Optional.
     */
    domainPattern?: string;

    /**
     * Password for external proxy authentication. Optional.
     */
    password?: string;

    /**
     * Username for external proxy authentication. Optional.
     */
    username?: string;
  }

  export interface NoneProxyConfig {
    /**
     * Type of proxy. Always 'none' for this config.
     */
    type: 'none';

    /**
     * Domain pattern for which this proxy should be used. If omitted, defaults to all
     * domains. Optional.
     */
    domainPattern?: string;
  }

  /**
   * Supplementary proxy settings. Optional.
   */
  export interface ProxySettings {
    /**
     * The TLS certificate IDs to trust. Optional.
     */
    caCertificates?: Array<string>;
  }
}

export interface SessionUpdateParams {
  /**
   * Set to `REQUEST_RELEASE` to request that the session complete. Use before
   * session's timeout to avoid additional charges.
   */
  status: 'REQUEST_RELEASE';

  /**
   * The Project ID. Can be found in
   * [Settings](https://www.browserbase.com/settings). Optional - if not provided,
   * the project will be inferred from the API key.
   */
  projectId?: string;
}

export interface SessionListParams {
  /**
   * Query sessions by user metadata. See
   * [Querying Sessions by User Metadata](/features/sessions#querying-sessions-by-user-metadata)
   * for the schema of this query.
   */
  q?: string;

  status?: 'PENDING' | 'RUNNING' | 'ERROR' | 'TIMED_OUT' | 'COMPLETED';
}

export interface SessionDebugParams {
  /**
   * Time-to-live of the generated live view URLs, in seconds. If omitted, the URLs
   * expire with the session, up to a maximum of 21600 seconds (6 hours).
   */
  expiresIn?: number;
}

Sessions.Downloads = Downloads;
Sessions.Logs = Logs;
Sessions.Recording = Recording;
Sessions.Uploads = Uploads;
Sessions.Replays = Replays;

export declare namespace Sessions {
  export {
    type Session as Session,
    type SessionLiveURLs as SessionLiveURLs,
    type SessionCreateResponse as SessionCreateResponse,
    type SessionRetrieveResponse as SessionRetrieveResponse,
    type SessionListResponse as SessionListResponse,
    type SessionCreateParams as SessionCreateParams,
    type SessionUpdateParams as SessionUpdateParams,
    type SessionListParams as SessionListParams,
    type SessionDebugParams as SessionDebugParams,
  };

  export { Downloads as Downloads };

  export { Logs as Logs, type SessionLog as SessionLog, type LogListResponse as LogListResponse };

  export {
    Recording as Recording,
    type SessionRecording as SessionRecording,
    type RecordingRetrieveResponse as RecordingRetrieveResponse,
  };

  export {
    Uploads as Uploads,
    type UploadCreateResponse as UploadCreateResponse,
    type UploadCreateParams as UploadCreateParams,
  };

  export { Replays as Replays, type ReplayRetrieveResponse as ReplayRetrieveResponse };
}
