// Single source of truth for the built-in security scan surfaces; flip to `true` to restore the security-scan UI and execution.
export const SECURITY_SCANS_ENABLED: boolean = false;

export type PolicyGateReadinessAction =
  | 'contact_admin'
  | 'fix_with_clark'
  | 'request_approval'
  | 'request_suppression'
  | 'rerun_gate'
  | 'view_report'
  | 'wait';

export type PolicyGateReadinessFindingSummary = {
  advisory: number;
  approvalRequired: number;
  blocking: number;
  suppressed: number;
};

export type PolicyGateReadinessFinding = {
  blocking: boolean;
  humanSummary?: string | null;
  locationsJson?: unknown[];
  remediationHintJson?: Record<string, unknown>;
  severity: 'critical' | 'high' | 'info' | 'low' | 'medium';
  technicalSummary?: string | null;
  title: string;
};

export type PolicyGateScanPhaseName = 'built_asset' | 'dependency_audit' | 'source';

export type PolicyGateScanPhaseState = 'complete' | 'failed' | 'pending' | 'running' | 'skipped';

export type PolicyGateScanPhaseProgress = {
  completedAt?: string;
  durationMs?: number;
  startedAt?: string;
  state: PolicyGateScanPhaseState;
};

export type PolicyGateScanProgress = {
  phases: Partial<Record<PolicyGateScanPhaseName, PolicyGateScanPhaseProgress>>;
  requiredPhases: PolicyGateScanPhaseName[];
};

export type PolicyGateReadinessItem = {
  actions: PolicyGateReadinessAction[];
  displayName?: string;
  findings?: PolicyGateReadinessFinding[];
  findingSummary: PolicyGateReadinessFindingSummary;
  itemId: string;
  itemType: 'security_agent' | 'security_scan';
  mode: 'advisory' | 'approval' | 'blocking' | 'report_only';
  policyId: string;
  policyVersionId: string;
  progress?: PolicyGateScanProgress;
  reviewRunId?: string;
  runs?: PolicyGateReadinessRun[];
  staleReason?: string;
  status: PolicyGateReadinessItemStatus;
};

export type PolicyGateReadinessRun = {
  completedAt?: string;
  createdAt?: string;
  decision: 'advisory_allowed' | 'allowed' | 'blocked' | 'error_blocked' | 'not_applicable' | null;
  errorCode?: string;
  errorMessage?: string;
  findingSummary: PolicyGateReadinessFindingSummary;
  reviewRunId: string;
  startedAt?: string;
  staleReason?: string | null;
  status: PolicyGateReadinessItemStatus;
};

export type PolicyGateReadinessItemStatus =
  | 'advisory_findings'
  | 'approval_required'
  | 'blocked'
  | 'failed'
  | 'missing'
  | 'passed'
  | 'running'
  | 'stale';

export type PolicyGateReadinessResponse = {
  items: PolicyGateReadinessItem[];
  status: PolicyGateReadinessStatus;
  target: PolicyGateReadinessTarget;
};

export type PolicyGateReadinessStatus = 'allowed' | 'approval_required' | 'blocked' | 'disabled' | 'failed' | 'running' | 'stale';

export type PolicyGateReadinessTarget = {
  applicationId: string;
  commitId: string;
  directoryContentsHash: string | null;
};

/**
 * Stable error code used in BadRequestError messages when a deploy is rejected
 * due to unresolved policy gate findings. Both server and client reference this
 * constant so the contract doesn't rely on fragile string matching.
 */
export const POLICY_GATE_BLOCKED_ERROR = 'POLICY_GATE_BLOCKED';

/**
 * User-facing message returned when a deploy is rejected because a dev-server
 * policy gate has not yet run against the version being deployed and the
 * current live edit state no longer matches that version. The dev-server scan
 * evaluates the live edit working tree, so running it for the first time
 * against a divergent live edit would review the wrong code. Surfaced directly
 * to the user, and shared so server and client agree on the exact text.
 */
export const POLICY_GATE_STALE_LIVE_EDIT_ERROR =
  'Policy gates can only run for the current app state. Deploy the current changes or restore to this commit and then deploy.';
