/**
 * cli:compute-page-diff — types.ts
 *
 * PURE spec-diff for ba-develop Phase 3a targeted re-runs. Compares the
 * canonical hash of every `pagespecs/<Entity>.<view>.md` machine block against
 * the previous `.run-snapshot.json` and reports added / modified / removed /
 * unchanged pages.
 *
 * This CLI performs NO inspection of generated `.tsx` files — the disk-drift
 * guard (closing the silent-skip class) lives in the orchestrator. See
 * `ba-develop/references/gates.md` § "Phase 3 pre-entry" and `disk-drift.ts`.
 */
import { z } from 'zod'

export const ComputePageDiffInputSchema = z
  .object({
    /**
     * Module folder holding the `pagespecs/` subdir and where
     * `.run-snapshot.json` lives — e.g. `.smartstack/ba/<APP>/<MODULE>`.
     */
    moduleRoot: z.string().min(1),
  })
  .strict()

export type ComputePageDiffInput = z.infer<typeof ComputePageDiffInputSchema>

export interface ModifiedPage {
  key: string
  previousHash: string
  currentHash: string
}

export interface PageDiff {
  /** Pages present now but absent from the snapshot (incl. every page on first run). */
  added: string[]
  /** Pages whose pagespec hash changed since the snapshot. */
  modified: ModifiedPage[]
  /** Pages in the snapshot whose pagespec file no longer exists. */
  removed: string[]
  /** Pages whose pagespec hash is identical to the snapshot. */
  unchanged: string[]
}

export interface ComputePageDiffReport {
  moduleRoot: string
  /** False on the first run (no snapshot) — the orchestrator then regenerates all. */
  snapshotFound: boolean
  diff: PageDiff
  /**
   * `added ∪ modified.key`, sorted. PURE spec-diff — the orchestrator unions
   * this with the disk-drift set before deciding what to regenerate.
   */
  toRegenerate: string[]
  /** Non-fatal pagespec parse issues (malformed file skipped). */
  warnings: string[]
}

export interface ValidationResult {
  valid: boolean
  errors: string[]
  warnings: string[]
  spec?: ComputePageDiffInput
}
