import type { ClassifiedRun } from "../../../../core/src/classify/classifier.js";
import type {
  CompatibilityContract,
  ProtocolFixture,
  ProtocolScenario,
} from "../../../../universal/fixtures/protocol/types.js";
import type { ProtocolViolation } from "../../../../universal/src/primitives/protocol/types.js";

export const PROTOCOL_CASE_KINDS = [
  "chunk-boundary",
  "flush-timing",
  "duplicate-frame",
  "missing-terminal-frame",
  "late-terminal-frame",
  "malformed-encoding",
  "version-skew",
  "stdout-contamination",
  "stderr-contamination",
  "transfer-validation",
] as const;

export type ProtocolCaseKind = (typeof PROTOCOL_CASE_KINDS)[number];

export const PROTOCOL_UNI_RULES = ["UNI-060", "UNI-061", "UNI-062", "UNI-063"] as const;

export type ProtocolUniRule = (typeof PROTOCOL_UNI_RULES)[number];

export type ProtocolCase = {
  caseId: string;
  kind: ProtocolCaseKind;
  rule: ProtocolUniRule;
  description: string;
  scenario: ExtendedProtocolScenario;
};

export type TransferValidationSpec = {
  declaredMediaType: string;
  declaredLength?: number;
  filename?: string;
  checksum?: string;
};

export type ProtocolContractSpec = {
  id: string;
  protocolVersion: string;
  frames: string[];
  terminalType: string;
  typedValue?: unknown;
  compatibilityContract?: CompatibilityContract;
  transfer?: TransferValidationSpec;
};

export type TransferValidationObservation = {
  bytes: string;
  declaredMediaType: string;
  observedMediaType?: string;
  filename?: string;
  declaredLength?: number;
  observedLength?: number;
  truncated?: boolean;
  checksumMatches?: boolean;
};

export type TransferValidationScenario = {
  scenarioId: string;
  kind: "transfer-validation";
  spec: TransferValidationSpec;
  observation: TransferValidationObservation;
};

export type ExtendedProtocolScenario = ProtocolScenario | TransferValidationScenario;

export type ProtocolCheckInput = Omit<ProtocolFixture, "scenarios"> & {
  scenarios: ExtendedProtocolScenario[];
};

export type ProtocolViolationsByRule = Partial<Record<ProtocolUniRule, ProtocolViolation[]>>;

export type ProtocolCheckResult = {
  fixtureId: string;
  holds: boolean;
  violations: ProtocolViolation[];
  violationsByRule: ProtocolViolationsByRule;
  classified: ClassifiedRun;
  laneEligibility: "advisory" | "blocking-eligible" | "blocking";
};
