import { afterEach, beforeEach, describe, expect, it } from "bun:test";
import { mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";

import { MemoryStore } from "../../src/memory/store.js";

describe("MemoryStore", () => {
  let tempDir: string;
  let backupDir: string;
  let store: MemoryStore;

  beforeEach(async () => {
    tempDir = await mkdtemp(join(tmpdir(), "tjwater-memory-"));
    backupDir = await mkdtemp(join(tmpdir(), "tjwater-memory-backup-"));
    store = new MemoryStore(tempDir, backupDir);
    await store.initialize();
  });

  afterEach(async () => {
    await rm(tempDir, { force: true, recursive: true });
    await rm(backupDir, { force: true, recursive: true });
  });

  it("dedupes exact duplicate memories", async () => {
    const first = await store.upsert("workspace", "project-1", {
      content: "DMA-2 nightly leakage analysis should compare against adjacent zones first.",
      source: "tool",
    });
    const second = await store.upsert("workspace", "project-1", {
      content: "DMA-2 nightly leakage analysis should compare against adjacent zones first.",
      source: "tool",
    });

    expect(first.changed).toBe(true);
    expect(second.changed).toBe(false);
    expect(second.detail).toBe("memory already existed");
  });

  it("allows rewritten memories when the content is not exactly the same", async () => {
    await store.upsert("workspace", "project-1", {
      content: "保存记忆前先查看当前 workspace memory，避免重复写入相同约束。",
      source: "tool",
    });

    const result = await store.upsert("workspace", "project-1", {
      content: "写入前先看一遍当前 workspace 记忆，避免把同样的约束重复保存进去。",
      source: "tool",
    });

    expect(result.changed).toBe(true);
    expect(result.detail).toBe("memory stored");
    expect(result.entry?.content).toBe("写入前先看一遍当前 workspace 记忆，避免把同样的约束重复保存进去。");
  });

  it("rejects replace when the new content would become an exact duplicate", async () => {
    const first = await store.upsert("user", "actor-1", {
      content: "回答时默认使用中文，并保持结论先行。",
      source: "tool",
    });
    const second = await store.upsert("user", "actor-1", {
      content: "回答要包含必要的文件路径引用。",
      source: "tool",
    });

    const result = await store.replace("user", "actor-1", second.entry?.id ?? "", {
      content: "回答时默认使用中文，并保持结论先行。",
      source: "tool",
    });

    expect(first.changed).toBe(true);
    expect(second.changed).toBe(true);
    expect(result.changed).toBe(false);
    expect(result.detail).toBe("replacement would duplicate an existing memory");
  });
});
