import { mkdtemp, readFile, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
import { JsonPlanStorage } from "../desktop/planStorage.js";
import type { PurchasePlan } from "../shared/contract.js";

const emptyPlan: PurchasePlan = { schemaVersion: 1, storeSort: "lines", requirements: [] };

describe("JsonPlanStorage", () => {
  it("returns an empty response before the first save", async () => {
    const dir = await mkdtemp(join(tmpdir(), "comparator-plan-"));
    const storage = new JsonPlanStorage(join(dir, "purchase-plan.json"));
    await expect(storage.loadResponse()).resolves.toEqual({ plan: null, updatedAt: null });
  });

  it("atomically persists the plan and timestamp", async () => {
    const dir = await mkdtemp(join(tmpdir(), "comparator-plan-"));
    const path = join(dir, "nested", "purchase-plan.json");
    const storage = new JsonPlanStorage(path);
    await expect(storage.set(emptyPlan, 1234)).resolves.toBe(1234);
    await expect(storage.loadResponse()).resolves.toEqual({ plan: emptyPlan, updatedAt: 1234 });
    expect(JSON.parse(await readFile(path, "utf8"))).toEqual({ plan: emptyPlan, updatedAt: 1234 });
  });

  it("rejects a malformed file instead of silently overwriting it", async () => {
    const dir = await mkdtemp(join(tmpdir(), "comparator-plan-"));
    const path = join(dir, "purchase-plan.json");
    await writeFile(path, "{}\n");
    await expect(new JsonPlanStorage(path).loadResponse()).rejects.toThrow("invalid purchase-plan file");
  });
});
