import type { z } from "zod";
import type {
  DecoderObservation,
  DecoderScenario,
} from "../../../../universal/fixtures/decoder/types.js";

export const BOUNDARY_PARTITIONS = [
  "missing",
  "null",
  "empty",
  "min",
  "max",
  "just-inside",
  "just-outside",
  "precision",
  "encoding",
  "enum",
  "cardinality",
  "uniqueness",
  "relation-ownership",
  "malformed",
] as const;

export type BoundaryPartition = (typeof BOUNDARY_PARTITIONS)[number];

export type BoundaryCase = {
  caseId: string;
  path: string;
  partition: BoundaryPartition;
  value: unknown;
  expectValid: boolean;
  description: string;
};

export type StrictDecoderGenerationSpec = {
  id: string;
  schema: z.ZodType;
  includeFallback?: boolean;
};

export type StrictDecoderRule = "UNI-030" | "UNI-031" | "UNI-032" | "UNI-033" | "UNI-034";

export type StrictDecoderViolation = {
  rule: StrictDecoderRule;
  scenarioId: string;
  kind: string;
  fact: string;
  details?: unknown;
};

export type StrictDecoderViolationsByRule = Partial<
  Record<StrictDecoderRule, StrictDecoderViolation[]>
>;

export type StrictDecoderCheckSpec = {
  id: string;
  schema: z.ZodType;
  includeFallback?: boolean;
  decode: (
    scenarios: DecoderScenario[],
  ) => Map<string, DecoderObservation> | Record<string, DecoderObservation>;
};

export type StrictDecoderCheckResult = {
  id: string;
  holds: boolean;
  scenarios: DecoderScenario[];
  violations: StrictDecoderViolationsByRule;
};
