import { generateStrictDecoderCases } from "./generate-strict-decoder-cases.js";
import { evaluateStrictDecoderScenarios } from "./evaluate-strict-decoder.js";
import type { StrictDecoderCheckResult, StrictDecoderCheckSpec } from "./types.js";

function assertNonEmptyString(value: string, field: string): void {
  if (value.trim().length === 0) {
    throw new Error(`${field} must be a non-empty string`);
  }
}

export function runStrictDecoderCheck(spec: StrictDecoderCheckSpec): StrictDecoderCheckResult {
  assertNonEmptyString(spec.id, "id");
  if (typeof spec.decode !== "function") {
    throw new Error("decode must be a function");
  }

  const scenarios = generateStrictDecoderCases({
    id: spec.id,
    schema: spec.schema,
    ...(spec.includeFallback === true ? { includeFallback: true } : {}),
  });
  const violations = evaluateStrictDecoderScenarios(scenarios, spec.decode(scenarios));
  const violationCount = Object.values(violations).reduce(
    (total, entries) => total + entries.length,
    0,
  );

  return {
    id: spec.id,
    holds: violationCount === 0,
    scenarios,
    violations,
  };
}
