import type { ExecutionContext } from "../../../schema/src/records/context.js";
import type { CoverageOutcome } from "../../../schema/src/records/coverage.js";
import type { Finding } from "../../../schema/src/records/finding.js";
import type {
  KernelStores,
  LaneEligibility,
} from "../classify/classifier.js";
import type { ContractStore } from "../contracts/store.js";
import type { DecisionStore } from "../decisions/store.js";
import type { CapabilityProfile } from "./capability.js";

export type { LaneEligibility };

export type ProofConditionWitness = {
  conditionId: string;
  description: string;
  satisfied: boolean;
};

export type DetectorMeasurements = Record<string, number | string | boolean>;

export type ProvenancedDetectorEvidence<Evidence> = {
  truthSource: "observed" | "inferred" | "universal" | "confirmed" | "legacy";
  payload: Evidence;
  visionOnly?: boolean;
};

export type DetectorOutcome<Evidence = unknown> = {
  detector: { id: string; version: string };
  class: string;
  severity: Finding["severity"];
  target: { kind: string; canonical: string };
  context: ExecutionContext;
  summary: string;
  evidence: ProvenancedDetectorEvidence<Evidence>[];
  artifacts: Finding["artifacts"];
  laneEligibility: LaneEligibility;
  proofConditionMet?: boolean;
  proofConditionWitness?: ProofConditionWitness;
  measurements?: DetectorMeasurements;
  scope: CoverageOutcome["scope"];
  violation: unknown;
  contractOrConfig?: unknown;
  contextDimensions?: Record<string, string>;
};

export type ReadonlyDecisionStore = Pick<
  DecisionStore,
  | "getDecision"
  | "isActive"
  | "activeIds"
  | "activeDecisionFor"
  | "queryDecisions"
  | "isHiddenFromDefault"
  | "reopenOnFingerprintChange"
>;

export type ReadonlyContractStore = Pick<
  ContractStore,
  | "getContract"
  | "getStorageKind"
  | "isActive"
  | "activeIds"
  | "confirmedContracts"
  | "inferredContracts"
>;

export type ReadonlyKernelStores = {
  decisions: ReadonlyDecisionStore;
  contracts: ReadonlyContractStore;
  authoritativeContracts: ReadonlySet<string>;
  now: string;
};

export type DetectorContext = {
  clock(): string;
  seed: string;
  capabilities: CapabilityProfile;
  readStores: ReadonlyKernelStores;
};

export interface Detector<Input, Evidence> {
  readonly id: string;
  readonly version: string;
  readonly defaultLane: LaneEligibility;
  evaluate(
    input: Input,
    context: DetectorContext,
  ): Promise<DetectorOutcome<Evidence>[]>;
}

export function asReadonlyKernelStores(stores: KernelStores): ReadonlyKernelStores {
  return stores;
}
