// src/layer/adapters/read-dedupe.ts
//
// ToolResultAdapter for Read-tool deduplication.
//
// Emits a `tests/install/blocks/EnvVarInstaller.test.tsAD:<hash>` sigil for every Read result. The sigil intentionally
// omits the `@T<turn>` suffix — Wave 3, which owns the per-session firstSeenTurn
// Map, will append `@T<N>` before freezing the compressed bytes. The hash is
// byte-identical to the one emitted by ReadCacheLayer (both derive it via
// fingerprintContent → SHA-256 first-12-hex).
//
// Load-bearing invariants (from types.ts):
//   Rule A — deterministic: same content bytes → same sigil → cache hit.
//   Rule B — conservative match: only "Read" tool name.
//   No side effects, no Date.now(), no Math.random().

import type { ToolResult } from "../../provider/canonical.ts";
import type { ToolResultAdapter, CompressedResult } from "./types.ts";
import { fingerprintContent } from "../../cache/fingerprint.ts";

export const readDedupe: ToolResultAdapter = {
  id: "read-dedupe",

  match(r: ToolResult): boolean {
    return r.toolName === "Read";
  },

  compress(r: ToolResult): CompressedResult {
    const rawContent: string =
      typeof r.content === "string" ? r.content : JSON.stringify(r.content);

    const hash = fingerprintContent(rawContent);
    // Emit partial sigil — Wave 3 appends @T<firstSeenTurn> from session state.
    const preview = `tests/install/blocks/EnvVarInstaller.test.tsAD:${hash}`;

    const bytesSaved =
      Buffer.byteLength(rawContent, "utf8") - Buffer.byteLength(preview, "utf8");

    return {
      preview,
      kbEntries: [],   // ReadCacheLayer already indexes via its own store
      bytesSaved,
      sigil: preview,
    };
  },
};
