/**
 * Types for the deterministic §B/§C1 mechanical binding-gate.
 *
 * The gate consumes a *structured* ruleset (data, not hardcoded logic) so that
 * the accumulation half (slice 2) can add a rule by appending one entry here +
 * one row to the live skrivekontrakt.md — the gate then enforces it next run.
 *
 * Source of truth for the seed rules: maskinrommet/docs/skrivekontrakt.md
 * (§B De ti reglene, §C1 Regelsjekk-gate, §C2 prosa-håndverk).
 */

export type Severity = "block" | "warn";

export type RuleKind =
  | "literal" // case-insensitive substring(s) — robust for æøå phrases
  | "regex" // forbidden regex pattern
  | "count" // count regex occurrences; flag when total > threshold (default 0)
  | "density"; // count occurrences; flag when rate exceeds threshold per `per` words

export interface Rule {
  /** Stable id, e.g. "B3-modell-referansepunkt". */
  id: string;
  /** Contract reference for the report, e.g. "§B-3 / §C1". */
  ref: string;
  severity: Severity;
  kind: RuleKind;
  /** Literal substrings (kind=literal) or regex sources (regex/count/density). */
  patterns: string[];
  /** Operator-facing direction: what the violation is + what to do. */
  message: string;
  /** count: max allowed before flagging (default 0). density: max per `per` words. */
  threshold?: number;
  /** density window size in words (default 50). */
  per?: number;
  /** Regex flags for regex/count/density (default "gi"). */
  flags?: string;
}

export interface Match {
  /** 1-based line in the ORIGINAL draft. */
  line: number;
  /** Short single-line excerpt around the match (from the original text). */
  excerpt: string;
}

export interface Violation {
  ruleId: string;
  ref: string;
  severity: Severity;
  message: string;
  matches: Match[];
  /** Observed count/rate for count|density rules. */
  observed?: number;
  threshold?: number;
}

export interface GateResult {
  draftPath: string | null;
  wordCount: number;
  blocks: Violation[];
  warns: Violation[];
  /** true iff there are no BLOCK violations — i.e. handoff is permitted. */
  passed: boolean;
}
