import { describe, expect, test } from "bun:test";
import { readFile } from "node:fs/promises";
import {
  historicalInventoryReport,
  inventoryOffloadStatus,
  reconcileHistoricalIncidents,
  type HistoricalIncidentDestination,
  type HistoricalIncidentRecord,
} from "./historical-reconciliation";

const fixtureUrl = new URL("../../test/fixtures/offload/status-incident-2026-07-18.json", import.meta.url);

function destination(seed: ReadonlyMap<string, string> = new Map()) {
  const records = new Map(seed);
  const created: Array<{ dedupKey: string; sourceId: string; sourceRecordId: string }> = [];
  const adapter: HistoricalIncidentDestination = {
    async findProvenance(dedupKey) {
      return records.get(dedupKey) ?? null;
    },
    async create(record) {
      created.push({
        dedupKey: record.dedupKey,
        sourceId: record.sourceId,
        sourceRecordId: record.sourceRecordId,
      });
      records.set(record.dedupKey, record.provenance);
    },
  };
  return { adapter, created, records };
}

describe("historical incident inventory", () => {
  test("inventories stable telemetry records without inventing event time or type", async () => {
    const source = JSON.parse(await readFile(fixtureUrl, "utf8"));

    const inventory = inventoryOffloadStatus(source);

    expect(inventory.sourceId).toBe("offload-status:2026-07-18");
    expect(inventory.records.map((record) => record.sourceRecordId)).toEqual([
      "dispatch",
      "queue-wedge:debian1",
      "job:rb-4e77b0",
      "job:rb-3d66a1",
    ]);
    expect(inventory.records.every((record) => record.originalTimestamp === null)).toBe(true);
    expect(inventory.records.every((record) => record.incidentType === "unresolved")).toBe(true);
    expect(inventory.records.every((record) => record.unresolvedReasons.includes("missing-original-timestamp"))).toBe(true);
    expect(inventory.records.every((record) => record.unresolvedReasons.includes("missing-canonical-type"))).toBe(true);
    expect(historicalInventoryReport(inventory).counts).toEqual({
      bySource: { "offload-status:2026-07-18": { discovered: 4, eligible: 0, unresolved: 4 } },
      byType: { unresolved: { discovered: 4, eligible: 0, unresolved: 4 } },
    });
  });
});

describe("historical incident reconciliation", () => {
  const eligible = {
    sourceId: "fixture:one",
    sourceRecordId: "record-7",
    originalTimestamp: "2026-07-18T05:00:00.000Z",
    incidentType: "runtime-session" as const,
    title: "Worker stopped",
    details: "Verified historical evidence",
    provenance: '{"source":"fixture:one","record":"record-7"}',
    unresolvedReasons: [],
  };

  test("creates an eligible record once and reports per-source/type counts", async () => {
    const target = destination();

    const first = await reconcileHistoricalIncidents([eligible], target.adapter);
    const second = await reconcileHistoricalIncidents([eligible], target.adapter);

    expect(target.created).toHaveLength(1);
    expect(first.counts.bySource["fixture:one"]).toEqual({ discovered: 1, eligible: 1, created: 1, existing: 0, unresolved: 0 });
    expect(first.counts.byType["runtime-session"]).toEqual({ discovered: 1, eligible: 1, created: 1, existing: 0, unresolved: 0 });
    expect(second.counts.bySource["fixture:one"]?.existing).toBe(1);
    expect(second.records[0]?.dedupKey).toBe(first.records[0]?.dedupKey);
  });

  test("fails closed on unresolved authority and provenance conflicts", async () => {
    const unresolved: HistoricalIncidentRecord = {
      ...eligible,
      originalTimestamp: null,
      incidentType: "unresolved",
      unresolvedReasons: ["missing-original-timestamp", "missing-canonical-type"],
    };
    const probe = destination();
    const initial = await reconcileHistoricalIncidents([eligible], probe.adapter);
    const key = initial.records[0]!.dedupKey;
    const target = destination(new Map([[key, '{"source":"different"}']]));

    const report = await reconcileHistoricalIncidents([unresolved, eligible], target.adapter);

    expect(target.created).toHaveLength(0);
    expect(report.records.map((record) => record.outcome)).toEqual(["unresolved", "unresolved"]);
    expect(report.records[1]?.unresolvedReasons).toEqual(["provenance-conflict"]);
    expect(report.counts.byType.unresolved?.unresolved).toBe(1);
    expect(report.counts.byType["runtime-session"]?.unresolved).toBe(1);
  });
});
