// src/core/oracle/meaning.ts
// SOURCE: ARCHITECTURE/32-LANGUAGE-OFFICIAL-13-IMPLEMENTATION-16.md
// Patch Set A2: Meaning as structured first-class value
// Patch Set 6: Enhanced obligations for term rewriting

import type { Val } from "../../../../src/core/eval/values";
import type { Evidence } from "../../../../src/core/provenance/evidence";
import { evidenceToVal } from "../../../../src/core/provenance/evidence";
import { meaning, isMeaning, type MeaningVal, type Obligation } from "../../../../src/core/meaning";

export type { Evidence, OracleEvidence, TransformEvidence, DerivedEvidence, ShellCheckEvidence, OracleVerdictEvidence } from "../../../../src/core/provenance/evidence";
export { meaning, isMeaning, type MeaningVal, type Obligation } from "../../../../src/core/meaning";

// Helper to convert old-style protocol Meaning to MeaningVal
function vStr(s: string): Val {
  return { tag: "Str", s };
}
function vNum(n: number): Val {
  return { tag: "Num", n };
}

/**
 * Convert MeaningVal to Map representation for backward compatibility.
 * Prefer using MeaningVal directly as it's now a first-class value.
 */
export function meaningToVal(m: MeaningVal): Val {
  const entries: Array<[Val, Val]> = [];
  entries.push([vStr("tag"), vStr("Meaning")]);

  if (m.denotation) entries.push([vStr("denotation"), m.denotation as Val]);
  if (m.confidence !== undefined) entries.push([vStr("confidence"), vNum(m.confidence)]);
  if (m.adoptEnvRef) entries.push([vStr("adoptEnvRef"), vStr(m.adoptEnvRef)]);
  if (m.residual) entries.push([vStr("residual"), m.residual]);
  if (m.rewrite) entries.push([vStr("rewrite"), m.rewrite]);
  if (m.obligation) entries.push([vStr("obligation"), m.obligation]);
  // Convert Evidence[] to Val (vector of maps) if present
  if (m.evidence) {
    const evidenceItems: Val[] = m.evidence.map(e => evidenceToVal(e));
    entries.push([vStr("evidence"), { tag: "Vector", items: evidenceItems }]);
  }
  if (m.trace) entries.push([vStr("trace"), m.trace as Val]);

  return { tag: "Map", entries };
}
