// 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 { RequestOptions } from '../../../internal/request-options';
import { path } from '../../../internal/utils/path';

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

  /**
   * Gets the repository projection of the active operator-reviewed scan report.
   * `scan_id` is the customer scan's stable request ID.
   *
   * @example
   * ```ts
   * const report =
   *   await client.managedDefense.vulnerabilityDiscovery.reports.get(
   *     '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',
   *     {
   *       account_id: '023e105f4ecef8ad9ca31a8372d0c353',
   *       repo_id: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',
   *     },
   *   );
   * ```
   */
  get(scanID: string, params: ReportGetParams, options?: RequestOptions): APIPromise<ReportGetResponse> {
    const { account_id, repo_id } = params;
    return (
      this._client.get(
        path`/accounts/${account_id}/managed-defense/vulnerability-discovery/repos/${repo_id}/scans/${scanID}/report`,
        options,
      ) as APIPromise<{ result: ReportGetResponse }>
    )._thenUnwrap((obj) => obj.result);
  }
}
export class Reports extends BaseReports {}

export interface ReportGetResponse {
  publication: ReportGetResponse.Publication;

  report: ReportGetResponse.Report;

  repository_id: string;

  scan_id: string;
}

export namespace ReportGetResponse {
  export interface Publication {
    published_at: string;

    revision_id: string;

    version: number;
  }

  export interface Report {
    findings: Array<Report.Finding>;

    overall_severity: 'critical' | 'high' | 'medium' | 'low' | 'info';

    repository_id: string;

    repository_name: string;

    summary: string;

    traffic_context: Report.TrafficContext;

    external_links?: Array<Report.ExternalLink>;

    limitations?: Array<string>;
  }

  export namespace Report {
    export interface Finding {
      id: string;

      conditions: Array<string>;

      cwe: string;

      impact: string;

      location: Finding.Location;

      reachability: Array<Finding.Reachability>;

      remediation: Finding.Remediation;

      root_cause: string;

      severity: 'critical' | 'high' | 'medium' | 'low' | 'info';

      severity_basis: string;

      summary: string;

      telemetry: Finding.Telemetry;

      title: string;

      trace: Array<Finding.Trace>;

      waf_rules: Finding.WAFRules | null;

      /**
       * Least-privileged position required to trigger the finding. Optional on legacy
       * report revisions.
       */
      attacker_position?: 'external' | 'authenticated' | 'internal' | 'post_compromise' | null;

      external_links?: Array<Finding.ExternalLink>;

      /**
       * One bounded unresolved proof question. Optional on legacy report revisions.
       */
      open_question?: string | null;

      /**
       * Method used or needed to close the proof. Optional on legacy report revisions.
       */
      proof_method?:
        | 'structural'
        | 'experimental'
        | 'acquired_source'
        | 'public_knowledge'
        | 'team_question'
        | null;

      /**
       * Current proof lifecycle state. Optional on legacy report revisions.
       */
      proof_state?:
        | 'closed'
        | 'pending_source'
        | 'pending_public'
        | 'pending_experiment'
        | 'pending_team'
        | null;
    }

    export namespace Finding {
      export interface Location {
        file: string;

        line: number;

        route: string | null;
      }

      export interface Reachability {
        consumer: string;

        reachable: boolean;

        via: string;
      }

      export interface Remediation {
        code_changes: string | null;

        strategy: string;
      }

      export interface Telemetry {
        references: Array<string>;

        state: 'no_route' | 'no_telemetry' | 'no_match' | 'matched';
      }

      export interface Trace {
        line: number;

        path: string;

        scope: string;

        why: string;
      }

      export interface WAFRules {
        broad: WAFRules.Broad | null;

        targeted: WAFRules.Targeted | null;
      }

      export namespace WAFRules {
        export interface Broad {
          action: 'block' | 'managed_challenge' | 'js_challenge' | 'log';

          confidence: 'low' | 'medium' | 'high';

          description: string;

          expression: string;

          false_positive_risk: string;

          name: string;

          rationale: string;
        }

        export interface Targeted {
          action: 'block' | 'managed_challenge' | 'js_challenge' | 'log';

          confidence: 'low' | 'medium' | 'high';

          description: string;

          expression: string;

          false_positive_risk: string;

          name: string;

          rationale: string;
        }
      }

      export interface ExternalLink {
        title: string;

        url: string;
      }
    }

    export interface TrafficContext {
      http: TrafficContext.HTTP | null;

      target: TrafficContext.Target | null;

      waf: TrafficContext.WAF | null;

      web_assets: TrafficContext.WebAssets | null;
    }

    export namespace TrafficContext {
      export interface HTTP {
        error_paths: Array<HTTP.ErrorPath>;

        hot_paths: Array<HTTP.HotPath>;

        request_volume: number;
      }

      export namespace HTTP {
        export interface ErrorPath {
          id: string;

          hits: number;

          host: string;

          path: string;

          status: number;
        }

        export interface HotPath {
          id: string;

          hits: number;

          host: string;

          path: string;

          top_status: number;
        }
      }

      export interface Target {
        hosts: Array<string>;

        kind: 'worker' | 'origin';

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

      export namespace Target {
        /**
         * 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 WAF {
        hit_volume: number;

        rules: Array<WAF.Rule>;
      }

      export namespace WAF {
        export interface Rule {
          id: string;

          hit_volume: number;

          paths: Array<Rule.Path>;

          rule_id: string;

          rule_version: number | null;
        }

        export namespace Rule {
          export interface Path {
            id: string;

            hit_volume: number;

            host: string;

            path: string;
          }
        }
      }

      export interface WebAssets {
        operations: Array<WebAssets.Operation>;

        paths: Array<WebAssets.Path>;

        risk_types: Array<WebAssets.RiskType>;
      }

      export namespace WebAssets {
        export interface Operation {
          id: string;

          endpoint: string;

          host: string;

          method: string;

          risk_labels: Array<Operation.RiskLabel>;

          performance?: Operation.Performance;
        }

        export namespace Operation {
          export interface RiskLabel {
            description: string | null;

            name: string;
          }

          export interface Performance {
            avg_origin_latency_ms: number | null;

            error_rate: number;

            estimated_requests: number;
          }
        }

        export interface Path {
          id: string;

          avg_origin_latency_ms: number | null;

          error_rate: number;

          estimated_requests: number;

          host: string;

          path: string;
        }

        export interface RiskType {
          description: string | null;

          name: string;

          operation_count: number;
        }
      }
    }

    export interface ExternalLink {
      title: string;

      url: string;
    }
  }
}

export interface ReportGetParams {
  account_id: string;

  repo_id: string;
}

export declare namespace Reports {
  export { type ReportGetResponse as ReportGetResponse, type ReportGetParams as ReportGetParams };
}
