// 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 { V4PagePaginationArray, type V4PagePaginationArrayParams } from '../../pagination';

export class Scans extends APIResource {
  /**
   * Creates and starts a new vulnerability scan. The response may include non-fatal
   * warnings in the `messages` array.
   *
   * @example
   * ```ts
   * const scan = await client.vulnerabilityScanner.scans.create(
   *   {
   *     account_id: '023e105f4ecef8ad9ca31a8372d0c353',
   *     credential_sets: {
   *       attacker: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',
   *       owner: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',
   *     },
   *     open_api: 'open_api',
   *     scan_type: 'bola',
   *     target_environment_id:
   *       '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',
   *   },
   * );
   * ```
   */
  create(params: ScanCreateParams, options?: Core.RequestOptions): Core.APIPromise<ScanCreateResponse> {
    const { account_id = this._client.accountId, ...body } = params;
    return (
      this._client.post(`/accounts/${account_id}/vuln_scanner/scans`, {
        body,
        ...options,
      }) as Core.APIPromise<{ result: ScanCreateResponse }>
    )._thenUnwrap((obj) => obj.result);
  }

  /**
   * Returns all scans for the account.
   *
   * @example
   * ```ts
   * // Automatically fetches more pages as needed.
   * for await (const scanListResponse of client.vulnerabilityScanner.scans.list(
   *   { account_id: '023e105f4ecef8ad9ca31a8372d0c353' },
   * )) {
   *   // ...
   * }
   * ```
   */
  list(
    params?: ScanListParams,
    options?: Core.RequestOptions,
  ): Core.PagePromise<ScanListResponsesV4PagePaginationArray, ScanListResponse>;
  list(
    options?: Core.RequestOptions,
  ): Core.PagePromise<ScanListResponsesV4PagePaginationArray, ScanListResponse>;
  list(
    params: ScanListParams | Core.RequestOptions = {},
    options?: Core.RequestOptions,
  ): Core.PagePromise<ScanListResponsesV4PagePaginationArray, ScanListResponse> {
    if (isRequestOptions(params)) {
      return this.list({}, params);
    }
    const { account_id = this._client.accountId, ...query } = params;
    return this._client.getAPIList(
      `/accounts/${account_id}/vuln_scanner/scans`,
      ScanListResponsesV4PagePaginationArray,
      { query, ...options },
    );
  }

  /**
   * Returns a single scan by ID.
   *
   * @example
   * ```ts
   * const scan = await client.vulnerabilityScanner.scans.get(
   *   '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',
   *   { account_id: '023e105f4ecef8ad9ca31a8372d0c353' },
   * );
   * ```
   */
  get(
    scanId: string,
    params?: ScanGetParams,
    options?: Core.RequestOptions,
  ): Core.APIPromise<ScanGetResponse>;
  get(scanId: string, options?: Core.RequestOptions): Core.APIPromise<ScanGetResponse>;
  get(
    scanId: string,
    params: ScanGetParams | Core.RequestOptions = {},
    options?: Core.RequestOptions,
  ): Core.APIPromise<ScanGetResponse> {
    if (isRequestOptions(params)) {
      return this.get(scanId, {}, params);
    }
    const { account_id = this._client.accountId } = params;
    return (
      this._client.get(`/accounts/${account_id}/vuln_scanner/scans/${scanId}`, options) as Core.APIPromise<{
        result: ScanGetResponse;
      }>
    )._thenUnwrap((obj) => obj.result);
  }
}

export class ScanListResponsesV4PagePaginationArray extends V4PagePaginationArray<ScanListResponse> {}

export interface ScanCreateResponse {
  /**
   * Scan identifier.
   */
  id: string;

  /**
   * The type of vulnerability scan.
   */
  scan_type: 'bola';

  /**
   * Current lifecycle status of the scan.
   */
  status: 'created' | 'scheduled' | 'planning' | 'running' | 'finished' | 'failed';

  /**
   * The target environment this scan runs against.
   */
  target_environment_id: string;

  /**
   * Vulnerability report produced after the scan completes. The shape depends on the
   * scan type. Present only for finished scans.
   */
  report?: ScanCreateResponse.Report | null;
}

export namespace ScanCreateResponse {
  /**
   * Vulnerability report produced after the scan completes. The shape depends on the
   * scan type. Present only for finished scans.
   */
  export interface Report {
    /**
     * Version 1 of the BOLA vulnerability scan report.
     */
    report: Report.Report;

    /**
     * Version of the report schema.
     */
    report_schema_version: 'v1';
  }

  export namespace Report {
    /**
     * Version 1 of the BOLA vulnerability scan report.
     */
    export interface Report {
      /**
       * Summary of all steps and findings.
       */
      summary: Report.Summary;

      /**
       * List of tests that were run.
       */
      tests: Array<Report.Test>;
    }

    export namespace Report {
      /**
       * Summary of all steps and findings.
       */
      export interface Summary {
        /**
         * Overall verdict of the vulnerability scan.
         */
        verdict: 'ok' | 'warning' | 'inconclusive';
      }

      /**
       * Result of a single test.
       */
      export interface Test {
        /**
         * Steps that were executed.
         */
        steps: Array<Test.Step>;

        /**
         * Verdict of this single test.
         */
        verdict: 'ok' | 'warning' | 'inconclusive';

        /**
         * Errors that prevented step execution.
         */
        preflight_errors?: Array<Test.PreflightError>;
      }

      export namespace Test {
        /**
         * A single step in a test.
         */
        export interface Step {
          /**
           * Assertions that were made against the received response.
           */
          assertions: Array<Step.Assertion>;

          /**
           * Errors the step encountered that may explain absent or incomplete fields.
           */
          errors?: Array<Step.Error>;

          /**
           * HTTP request that was made, if any.
           */
          request?: Step.Request | null;

          /**
           * HTTP response that was received, if any.
           */
          response?: Step.Response | null;
        }

        export namespace Step {
          /**
           * Assertion that was made against the received response.
           */
          export interface Assertion {
            /**
             * Human-readable description of the assertion, explaining what was checked.
             */
            description: string;

            /**
             * Kind of assertion.
             */
            kind: Assertion.Kind;

            /**
             * Observed value on which the assertion was made.
             */
            observed: number | null;

            /**
             * Outcome of the assertion.
             */
            outcome: 'ok' | 'fail' | 'inconclusive';
          }

          export namespace Assertion {
            /**
             * Kind of assertion.
             */
            export interface Kind {
              /**
               * Range of HTTP status codes.
               */
              parameters: Kind.Parameters;

              type: 'http_status_within_range';
            }

            export namespace Kind {
              /**
               * Range of HTTP status codes.
               */
              export interface Parameters {
                /**
                 * Maximum (inclusive) status code of the range.
                 */
                max: number;

                /**
                 * Minimum (inclusive) status code of the range.
                 */
                min: number;
              }
            }
          }

          /**
           * Error that occurred during a test.
           */
          export interface Error {
            /**
             * Human-readable error description.
             */
            description: string;

            /**
             * Numeric error code identifying the class of error, if available.
             */
            error_code?: number | null;
          }

          /**
           * HTTP request that was made, if any.
           */
          export interface Request {
            /**
             * Credential set that was used.
             */
            credential_set: Request.CredentialSet;

            /**
             * Names of headers that were sent.
             */
            header_names: Array<string>;

            /**
             * HTTP method.
             */
            method: 'GET' | 'DELETE' | 'PATCH' | 'POST' | 'PUT';

            /**
             * Exact and full URL (including host, query parameters) that was requested.
             */
            url: string;

            /**
             * Variable captures requested for this step.
             */
            variable_captures: Array<Request.VariableCapture>;

            /**
             * Request body, if any.
             */
            body?: unknown | null;
          }

          export namespace Request {
            /**
             * Credential set that was used.
             */
            export interface CredentialSet {
              /**
               * ID of the credential set.
               */
              id: string;

              /**
               * Role of the credential set.
               */
              role: 'owner' | 'attacker';
            }

            /**
             * A variable to capture from the response body.
             */
            export interface VariableCapture {
              /**
               * JSONPath expression used for capture, e.g. `"$.id"`.
               */
              json_path: string;

              /**
               * Variable name, e.g. `"resource_id"`.
               */
              name: string;
            }
          }

          /**
           * HTTP response that was received, if any.
           */
          export interface Response {
            /**
             * HTTP response body.
             */
            body: Response.Kind | Response.UnionMember1 | Response.UnionMember2 | Response.UnionMember3;

            /**
             * Names of headers that were received.
             */
            header_names: Array<string>;

            /**
             * HTTP status code.
             */
            status: number;

            /**
             * HTTP status text, if available for the status code.
             */
            status_text?: string | null;
          }

          export namespace Response {
            /**
             * No body was received.
             */
            export interface Kind {
              kind: 'not_found';
            }

            /**
             * Body received but unable to read as UTF-8. Raw bytes, base64-encoded.
             */
            export interface UnionMember1 {
              contents: string;

              kind: 'bytes';

              truncated: boolean;
            }

            /**
             * Body received as valid UTF-8 text but not valid JSON.
             */
            export interface UnionMember2 {
              contents: string;

              kind: 'text';

              truncated: boolean;
            }

            /**
             * Body received as valid JSON.
             */
            export interface UnionMember3 {
              contents: string;

              kind: 'json';

              truncated: boolean;
            }
          }
        }

        /**
         * Error that occurred during a test.
         */
        export interface PreflightError {
          /**
           * Human-readable error description.
           */
          description: string;

          /**
           * Numeric error code identifying the class of error, if available.
           */
          error_code?: number | null;
        }
      }
    }
  }
}

export interface ScanListResponse {
  /**
   * Scan identifier.
   */
  id: string;

  /**
   * The type of vulnerability scan.
   */
  scan_type: 'bola';

  /**
   * Current lifecycle status of the scan.
   */
  status: 'created' | 'scheduled' | 'planning' | 'running' | 'finished' | 'failed';

  /**
   * The target environment this scan runs against.
   */
  target_environment_id: string;

  /**
   * Vulnerability report produced after the scan completes. The shape depends on the
   * scan type. Present only for finished scans.
   */
  report?: ScanListResponse.Report | null;
}

export namespace ScanListResponse {
  /**
   * Vulnerability report produced after the scan completes. The shape depends on the
   * scan type. Present only for finished scans.
   */
  export interface Report {
    /**
     * Version 1 of the BOLA vulnerability scan report.
     */
    report: Report.Report;

    /**
     * Version of the report schema.
     */
    report_schema_version: 'v1';
  }

  export namespace Report {
    /**
     * Version 1 of the BOLA vulnerability scan report.
     */
    export interface Report {
      /**
       * Summary of all steps and findings.
       */
      summary: Report.Summary;

      /**
       * List of tests that were run.
       */
      tests: Array<Report.Test>;
    }

    export namespace Report {
      /**
       * Summary of all steps and findings.
       */
      export interface Summary {
        /**
         * Overall verdict of the vulnerability scan.
         */
        verdict: 'ok' | 'warning' | 'inconclusive';
      }

      /**
       * Result of a single test.
       */
      export interface Test {
        /**
         * Steps that were executed.
         */
        steps: Array<Test.Step>;

        /**
         * Verdict of this single test.
         */
        verdict: 'ok' | 'warning' | 'inconclusive';

        /**
         * Errors that prevented step execution.
         */
        preflight_errors?: Array<Test.PreflightError>;
      }

      export namespace Test {
        /**
         * A single step in a test.
         */
        export interface Step {
          /**
           * Assertions that were made against the received response.
           */
          assertions: Array<Step.Assertion>;

          /**
           * Errors the step encountered that may explain absent or incomplete fields.
           */
          errors?: Array<Step.Error>;

          /**
           * HTTP request that was made, if any.
           */
          request?: Step.Request | null;

          /**
           * HTTP response that was received, if any.
           */
          response?: Step.Response | null;
        }

        export namespace Step {
          /**
           * Assertion that was made against the received response.
           */
          export interface Assertion {
            /**
             * Human-readable description of the assertion, explaining what was checked.
             */
            description: string;

            /**
             * Kind of assertion.
             */
            kind: Assertion.Kind;

            /**
             * Observed value on which the assertion was made.
             */
            observed: number | null;

            /**
             * Outcome of the assertion.
             */
            outcome: 'ok' | 'fail' | 'inconclusive';
          }

          export namespace Assertion {
            /**
             * Kind of assertion.
             */
            export interface Kind {
              /**
               * Range of HTTP status codes.
               */
              parameters: Kind.Parameters;

              type: 'http_status_within_range';
            }

            export namespace Kind {
              /**
               * Range of HTTP status codes.
               */
              export interface Parameters {
                /**
                 * Maximum (inclusive) status code of the range.
                 */
                max: number;

                /**
                 * Minimum (inclusive) status code of the range.
                 */
                min: number;
              }
            }
          }

          /**
           * Error that occurred during a test.
           */
          export interface Error {
            /**
             * Human-readable error description.
             */
            description: string;

            /**
             * Numeric error code identifying the class of error, if available.
             */
            error_code?: number | null;
          }

          /**
           * HTTP request that was made, if any.
           */
          export interface Request {
            /**
             * Credential set that was used.
             */
            credential_set: Request.CredentialSet;

            /**
             * Names of headers that were sent.
             */
            header_names: Array<string>;

            /**
             * HTTP method.
             */
            method: 'GET' | 'DELETE' | 'PATCH' | 'POST' | 'PUT';

            /**
             * Exact and full URL (including host, query parameters) that was requested.
             */
            url: string;

            /**
             * Variable captures requested for this step.
             */
            variable_captures: Array<Request.VariableCapture>;

            /**
             * Request body, if any.
             */
            body?: unknown | null;
          }

          export namespace Request {
            /**
             * Credential set that was used.
             */
            export interface CredentialSet {
              /**
               * ID of the credential set.
               */
              id: string;

              /**
               * Role of the credential set.
               */
              role: 'owner' | 'attacker';
            }

            /**
             * A variable to capture from the response body.
             */
            export interface VariableCapture {
              /**
               * JSONPath expression used for capture, e.g. `"$.id"`.
               */
              json_path: string;

              /**
               * Variable name, e.g. `"resource_id"`.
               */
              name: string;
            }
          }

          /**
           * HTTP response that was received, if any.
           */
          export interface Response {
            /**
             * HTTP response body.
             */
            body: Response.Kind | Response.UnionMember1 | Response.UnionMember2 | Response.UnionMember3;

            /**
             * Names of headers that were received.
             */
            header_names: Array<string>;

            /**
             * HTTP status code.
             */
            status: number;

            /**
             * HTTP status text, if available for the status code.
             */
            status_text?: string | null;
          }

          export namespace Response {
            /**
             * No body was received.
             */
            export interface Kind {
              kind: 'not_found';
            }

            /**
             * Body received but unable to read as UTF-8. Raw bytes, base64-encoded.
             */
            export interface UnionMember1 {
              contents: string;

              kind: 'bytes';

              truncated: boolean;
            }

            /**
             * Body received as valid UTF-8 text but not valid JSON.
             */
            export interface UnionMember2 {
              contents: string;

              kind: 'text';

              truncated: boolean;
            }

            /**
             * Body received as valid JSON.
             */
            export interface UnionMember3 {
              contents: string;

              kind: 'json';

              truncated: boolean;
            }
          }
        }

        /**
         * Error that occurred during a test.
         */
        export interface PreflightError {
          /**
           * Human-readable error description.
           */
          description: string;

          /**
           * Numeric error code identifying the class of error, if available.
           */
          error_code?: number | null;
        }
      }
    }
  }
}

export interface ScanGetResponse {
  /**
   * Scan identifier.
   */
  id: string;

  /**
   * The type of vulnerability scan.
   */
  scan_type: 'bola';

  /**
   * Current lifecycle status of the scan.
   */
  status: 'created' | 'scheduled' | 'planning' | 'running' | 'finished' | 'failed';

  /**
   * The target environment this scan runs against.
   */
  target_environment_id: string;

  /**
   * Vulnerability report produced after the scan completes. The shape depends on the
   * scan type. Present only for finished scans.
   */
  report?: ScanGetResponse.Report | null;
}

export namespace ScanGetResponse {
  /**
   * Vulnerability report produced after the scan completes. The shape depends on the
   * scan type. Present only for finished scans.
   */
  export interface Report {
    /**
     * Version 1 of the BOLA vulnerability scan report.
     */
    report: Report.Report;

    /**
     * Version of the report schema.
     */
    report_schema_version: 'v1';
  }

  export namespace Report {
    /**
     * Version 1 of the BOLA vulnerability scan report.
     */
    export interface Report {
      /**
       * Summary of all steps and findings.
       */
      summary: Report.Summary;

      /**
       * List of tests that were run.
       */
      tests: Array<Report.Test>;
    }

    export namespace Report {
      /**
       * Summary of all steps and findings.
       */
      export interface Summary {
        /**
         * Overall verdict of the vulnerability scan.
         */
        verdict: 'ok' | 'warning' | 'inconclusive';
      }

      /**
       * Result of a single test.
       */
      export interface Test {
        /**
         * Steps that were executed.
         */
        steps: Array<Test.Step>;

        /**
         * Verdict of this single test.
         */
        verdict: 'ok' | 'warning' | 'inconclusive';

        /**
         * Errors that prevented step execution.
         */
        preflight_errors?: Array<Test.PreflightError>;
      }

      export namespace Test {
        /**
         * A single step in a test.
         */
        export interface Step {
          /**
           * Assertions that were made against the received response.
           */
          assertions: Array<Step.Assertion>;

          /**
           * Errors the step encountered that may explain absent or incomplete fields.
           */
          errors?: Array<Step.Error>;

          /**
           * HTTP request that was made, if any.
           */
          request?: Step.Request | null;

          /**
           * HTTP response that was received, if any.
           */
          response?: Step.Response | null;
        }

        export namespace Step {
          /**
           * Assertion that was made against the received response.
           */
          export interface Assertion {
            /**
             * Human-readable description of the assertion, explaining what was checked.
             */
            description: string;

            /**
             * Kind of assertion.
             */
            kind: Assertion.Kind;

            /**
             * Observed value on which the assertion was made.
             */
            observed: number | null;

            /**
             * Outcome of the assertion.
             */
            outcome: 'ok' | 'fail' | 'inconclusive';
          }

          export namespace Assertion {
            /**
             * Kind of assertion.
             */
            export interface Kind {
              /**
               * Range of HTTP status codes.
               */
              parameters: Kind.Parameters;

              type: 'http_status_within_range';
            }

            export namespace Kind {
              /**
               * Range of HTTP status codes.
               */
              export interface Parameters {
                /**
                 * Maximum (inclusive) status code of the range.
                 */
                max: number;

                /**
                 * Minimum (inclusive) status code of the range.
                 */
                min: number;
              }
            }
          }

          /**
           * Error that occurred during a test.
           */
          export interface Error {
            /**
             * Human-readable error description.
             */
            description: string;

            /**
             * Numeric error code identifying the class of error, if available.
             */
            error_code?: number | null;
          }

          /**
           * HTTP request that was made, if any.
           */
          export interface Request {
            /**
             * Credential set that was used.
             */
            credential_set: Request.CredentialSet;

            /**
             * Names of headers that were sent.
             */
            header_names: Array<string>;

            /**
             * HTTP method.
             */
            method: 'GET' | 'DELETE' | 'PATCH' | 'POST' | 'PUT';

            /**
             * Exact and full URL (including host, query parameters) that was requested.
             */
            url: string;

            /**
             * Variable captures requested for this step.
             */
            variable_captures: Array<Request.VariableCapture>;

            /**
             * Request body, if any.
             */
            body?: unknown | null;
          }

          export namespace Request {
            /**
             * Credential set that was used.
             */
            export interface CredentialSet {
              /**
               * ID of the credential set.
               */
              id: string;

              /**
               * Role of the credential set.
               */
              role: 'owner' | 'attacker';
            }

            /**
             * A variable to capture from the response body.
             */
            export interface VariableCapture {
              /**
               * JSONPath expression used for capture, e.g. `"$.id"`.
               */
              json_path: string;

              /**
               * Variable name, e.g. `"resource_id"`.
               */
              name: string;
            }
          }

          /**
           * HTTP response that was received, if any.
           */
          export interface Response {
            /**
             * HTTP response body.
             */
            body: Response.Kind | Response.UnionMember1 | Response.UnionMember2 | Response.UnionMember3;

            /**
             * Names of headers that were received.
             */
            header_names: Array<string>;

            /**
             * HTTP status code.
             */
            status: number;

            /**
             * HTTP status text, if available for the status code.
             */
            status_text?: string | null;
          }

          export namespace Response {
            /**
             * No body was received.
             */
            export interface Kind {
              kind: 'not_found';
            }

            /**
             * Body received but unable to read as UTF-8. Raw bytes, base64-encoded.
             */
            export interface UnionMember1 {
              contents: string;

              kind: 'bytes';

              truncated: boolean;
            }

            /**
             * Body received as valid UTF-8 text but not valid JSON.
             */
            export interface UnionMember2 {
              contents: string;

              kind: 'text';

              truncated: boolean;
            }

            /**
             * Body received as valid JSON.
             */
            export interface UnionMember3 {
              contents: string;

              kind: 'json';

              truncated: boolean;
            }
          }
        }

        /**
         * Error that occurred during a test.
         */
        export interface PreflightError {
          /**
           * Human-readable error description.
           */
          description: string;

          /**
           * Numeric error code identifying the class of error, if available.
           */
          error_code?: number | null;
        }
      }
    }
  }
}

export interface ScanCreateParams {
  /**
   * Path param: Identifier.
   */
  account_id?: string;

  /**
   * Body param: Credential set references for a BOLA scan. The scanner uses the
   * `owner` credentials for legitimate requests and the `attacker` credentials to
   * attempt unauthorized access.
   */
  credential_sets: ScanCreateParams.CredentialSets;

  /**
   * Body param: OpenAPI schema definition for the API under test. The scanner uses
   * this to discover endpoints and construct requests.
   */
  open_api: string;

  /**
   * Body param
   */
  scan_type: 'bola';

  /**
   * Body param: The target environment to scan.
   */
  target_environment_id: string;
}

export namespace ScanCreateParams {
  /**
   * Credential set references for a BOLA scan. The scanner uses the `owner`
   * credentials for legitimate requests and the `attacker` credentials to attempt
   * unauthorized access.
   */
  export interface CredentialSets {
    /**
     * Credential set ID for the attacker.
     */
    attacker: string;

    /**
     * Credential set ID for the resource owner.
     */
    owner: string;
  }
}

export interface ScanListParams extends V4PagePaginationArrayParams {
  /**
   * Path param: Identifier.
   */
  account_id?: string;
}

export interface ScanGetParams {
  /**
   * Identifier.
   */
  account_id?: string;
}

Scans.ScanListResponsesV4PagePaginationArray = ScanListResponsesV4PagePaginationArray;

export declare namespace Scans {
  export {
    type ScanCreateResponse as ScanCreateResponse,
    type ScanListResponse as ScanListResponse,
    type ScanGetResponse as ScanGetResponse,
    ScanListResponsesV4PagePaginationArray as ScanListResponsesV4PagePaginationArray,
    type ScanCreateParams as ScanCreateParams,
    type ScanListParams as ScanListParams,
    type ScanGetParams as ScanGetParams,
  };
}
