import assert from "node:assert/strict";
import test from "node:test";
import { OcrCheckpointStore } from "../../lib/client/ocr/checkpoints.ts";

class MemoryKeyValue {
  records = new Map();
  async get(key) { return this.records.get(key); }
  async put(value, key) { this.records.set(key, structuredClone(value)); }
  async delete(key) { this.records.delete(key); }
  async getAllKeys() { return [...this.records.keys()]; }
}

test("saves, restores, overwrites, and clears per-page OCR checkpoints", async () => {
  const backend = new MemoryKeyValue();
  const checkpoints = new OcrCheckpointStore(backend);
  const page = {
    bookId: "book-1",
    sourceFingerprint: "sha256-1",
    pageNumber: 2,
    width: 600,
    height: 800,
    blocks: [{ text: "识别正文", x: 1, y: 2, width: 3, height: 4, confidence: 92 }],
    completedAt: "2026-08-12T01:00:00.000Z",
  };

  await checkpoints.save(page);
  assert.deepEqual(await checkpoints.get("book-1", "sha256-1", 2), page);
  await checkpoints.save({ ...page, blocks: [{ ...page.blocks[0], text: "重新识别" }] });
  assert.equal((await checkpoints.list("book-1", "sha256-1"))[0].blocks[0].text, "重新识别");
  await checkpoints.clearPage("book-1", "sha256-1", 2);
  assert.equal(await checkpoints.get("book-1", "sha256-1", 2), null);
});

test("keeps checkpoints for different source versions isolated", async () => {
  const backend = new MemoryKeyValue();
  const checkpoints = new OcrCheckpointStore(backend);
  for (const sourceFingerprint of ["old", "new"]) {
    await checkpoints.save({
      bookId: "book-1",
      sourceFingerprint,
      pageNumber: 1,
      width: 1,
      height: 1,
      blocks: [],
      completedAt: "2026-08-12T01:00:00.000Z",
    });
  }
  assert.equal((await checkpoints.list("book-1", "old")).length, 1);
  assert.equal((await checkpoints.list("book-1", "new")).length, 1);
  await checkpoints.clearBook("book-1");
  assert.equal(backend.records.size, 0);
});
