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

import { APIResource } from '../../../core/resource';
import { APIPromise } from '../../../core/api-promise';
import {
  CursorLimitPagination,
  type CursorLimitPaginationParams,
  PagePromise,
} from '../../../core/pagination';
import { buildHeaders } from '../../../internal/headers';
import { RequestOptions } from '../../../internal/request-options';
import { path } from '../../../internal/utils/path';

export class BaseRepositories extends APIResource {
  static override readonly _key: readonly ['managedDefense', 'vulnerabilityDiscovery', 'repositories'] =
    Object.freeze(['managedDefense', 'vulnerabilityDiscovery', 'repositories'] as const);

  /**
   * Creates an upload repository or reserves an asynchronous deployed Worker import
   * by name. Worker imports require Idempotency-Key.
   *
   * @example
   * ```ts
   * const repository =
   *   await client.managedDefense.vulnerabilityDiscovery.repositories.create(
   *     {
   *       account_id: '023e105f4ecef8ad9ca31a8372d0c353',
   *       name: 'x',
   *     },
   *   );
   * ```
   */
  create(params: RepositoryCreateParams, options?: RequestOptions): APIPromise<RepositoryCreateResponse> {
    const { account_id, 'Idempotency-Key': idempotencyKey, ...body } = params;
    return (
      this._client.post(path`/accounts/${account_id}/managed-defense/vulnerability-discovery/repos`, {
        body,
        ...options,
        headers: buildHeaders([
          { ...(idempotencyKey != null ? { 'Idempotency-Key': idempotencyKey } : undefined) },
          options?.headers,
        ]),
      }) as APIPromise<{ result: RepositoryCreateResponse }>
    )._thenUnwrap((obj) => obj.result);
  }

  /**
   * Lists repositories available for vulnerability discovery in an account.
   *
   * @example
   * ```ts
   * // Automatically fetches more pages as needed.
   * for await (const repositoryListResponse of client.managedDefense.vulnerabilityDiscovery.repositories.list(
   *   { account_id: '023e105f4ecef8ad9ca31a8372d0c353' },
   * )) {
   *   // ...
   * }
   * ```
   */
  list(
    params: RepositoryListParams,
    options?: RequestOptions,
  ): PagePromise<RepositoryListResponsesCursorLimitPagination, RepositoryListResponse> {
    const { account_id, ...query } = params;
    return this._client.getAPIList(
      path`/accounts/${account_id}/managed-defense/vulnerability-discovery/repos`,
      CursorLimitPagination<RepositoryListResponse>,
      { query, ...options },
    );
  }

  /**
   * Gets repository metadata, source readiness, and customer scan history.
   *
   * @example
   * ```ts
   * const repository =
   *   await client.managedDefense.vulnerabilityDiscovery.repositories.get(
   *     '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',
   *     { account_id: '023e105f4ecef8ad9ca31a8372d0c353' },
   *   );
   * ```
   */
  get(
    repoID: string,
    params: RepositoryGetParams,
    options?: RequestOptions,
  ): APIPromise<RepositoryGetResponse> {
    const { account_id, ...query } = params;
    return (
      this._client.get(
        path`/accounts/${account_id}/managed-defense/vulnerability-discovery/repos/${repoID}`,
        { query, ...options },
      ) as APIPromise<{ result: RepositoryGetResponse }>
    )._thenUnwrap((obj) => obj.result);
  }
}
export class Repositories extends BaseRepositories {}

export type RepositoryListResponsesCursorLimitPagination = CursorLimitPagination<RepositoryListResponse>;

export type RepositoryCreateResponse =
  | RepositoryCreateResponse.UnionMember0
  | RepositoryCreateResponse.Repository;

export namespace RepositoryCreateResponse {
  export interface UnionMember0 {
    repository: UnionMember0.Repository;

    upload: UnionMember0.Upload;
  }

  export namespace UnionMember0 {
    export interface Repository {
      id: string;

      name: string;

      readiness: 'awaiting_source' | 'processing' | 'ready' | 'failed';

      source: 'upload' | 'worker';

      import_error?: Repository.ImportError;
    }

    export namespace Repository {
      export interface ImportError {
        code: 'worker_import_failed';

        message: 'Worker import failed.';
      }
    }

    export interface Upload {
      token: string;

      expires_in: 3600;

      remote: string;
    }
  }

  export interface Repository {
    repository: Repository.Repository;
  }

  export namespace Repository {
    export interface Repository {
      id: string;

      name: string;

      readiness: 'awaiting_source' | 'processing' | 'ready' | 'failed';

      source: 'upload' | 'worker';

      import_error?: Repository.ImportError;
    }

    export namespace Repository {
      export interface ImportError {
        code: 'worker_import_failed';

        message: 'Worker import failed.';
      }
    }
  }
}

export interface RepositoryListResponse {
  id: string;

  created_at: string;

  name: string;

  readiness: 'awaiting_source' | 'processing' | 'ready' | 'failed';

  source: 'upload' | 'worker';

  import_error?: RepositoryListResponse.ImportError;
}

export namespace RepositoryListResponse {
  export interface ImportError {
    code: 'worker_import_failed';

    message: 'Worker import failed.';
  }
}

export interface RepositoryGetResponse {
  repository: RepositoryGetResponse.Repository;

  scans: Array<RepositoryGetResponse.Scan>;
}

export namespace RepositoryGetResponse {
  export interface Repository {
    id: string;

    created_at: string;

    name: string;

    readiness: 'awaiting_source' | 'processing' | 'ready' | 'failed';

    source: 'upload' | 'worker';

    import_error?: Repository.ImportError;
  }

  export namespace Repository {
    export interface ImportError {
      code: 'worker_import_failed';

      message: 'Worker import failed.';
    }
  }

  export interface Scan {
    id: string;

    completed_at: string | null;

    message: string | null;

    phase: 'provisioning' | 'indexing' | 'analyzing' | 'reporting' | 'finalizing' | null;

    repositories: Array<Scan.Repository>;

    started_at: string | null;

    status: 'requested' | 'accepted' | 'running' | 'completed' | 'failed' | 'rejected' | 'cancelled';

    submitted_at: string;

    /**
     * UTC ISO-8601 interval. Start is inclusive, end is exclusive, and the interval
     * must be positive and at most seven days.
     */
    telemetry_window?: Scan.TelemetryWindow;
  }

  export namespace Scan {
    export interface Repository {
      id: string;

      name: string;

      phase: 'provisioning' | 'indexing' | 'analyzing' | 'reporting' | 'finalizing' | null;

      report_status: 'not_ready' | 'pending_review' | 'published' | 'withdrawn';

      status: 'requested' | 'accepted' | 'running' | 'completed' | 'failed' | 'rejected' | 'cancelled';
    }

    /**
     * UTC ISO-8601 interval. Start is inclusive, end is exclusive, and the interval
     * must be positive and at most seven days.
     */
    export interface TelemetryWindow {
      end: string;

      start: string;
    }
  }
}

export interface RepositoryCreateParams {
  /**
   * Path param
   */
  account_id: string;

  /**
   * Body param
   */
  name: string;

  /**
   * Body param
   */
  worker_script_name?: string;

  /**
   * Header param: Optional. Supply this header to safely retry a request. Required
   * when `worker_script_name` is supplied.
   */
  'Idempotency-Key'?: string;
}

export interface RepositoryListParams extends CursorLimitPaginationParams {
  /**
   * Path param
   */
  account_id: string;
}

export interface RepositoryGetParams {
  /**
   * Path param
   */
  account_id: string;

  /**
   * Query param
   */
  scan_cursor?: string;

  /**
   * Query param
   */
  scan_limit?: number;
}

export declare namespace Repositories {
  export {
    type RepositoryCreateResponse as RepositoryCreateResponse,
    type RepositoryListResponse as RepositoryListResponse,
    type RepositoryGetResponse as RepositoryGetResponse,
    type RepositoryListResponsesCursorLimitPagination as RepositoryListResponsesCursorLimitPagination,
    type RepositoryCreateParams as RepositoryCreateParams,
    type RepositoryListParams as RepositoryListParams,
    type RepositoryGetParams as RepositoryGetParams,
  };
}
