import { afterEach, describe, expect, test } from "bun:test";
import { mkdtempSync, rmSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "node:os";
import {
  mergeRepoRuns,
  readRunHistory,
  recentRepoRuns,
  writeRunHistory,
  type StoredGhRun,
} from "./ghci-run-history";

const baseRun: StoredGhRun = {
  id: 1,
  run_attempt: 1,
  run_number: 10,
  name: "gate",
  head_branch: "main",
  head_sha: "sha-1",
  display_title: "Gate",
  status: "completed",
  conclusion: "success",
  workflow_id: 9,
  html_url: "https://github.com/acme/app/actions/runs/1",
  created_at: "2026-07-19T08:00:00.000Z",
  updated_at: "2026-07-19T09:00:00.000Z",
};

describe("ghci-run-history", () => {
  let dir = "";

  afterEach(() => {
    if (dir) rmSync(dir, { recursive: true, force: true });
    delete process.env.OVERDECK_STATE_DIR;
    dir = "";
  });

  test("merges runs by id+attempt and keeps newest first", () => {
    const store = {};
    mergeRepoRuns(store, "acme/app", [baseRun], "2026-07-19T10:00:00.000Z");
    const newer = { ...baseRun, id: 2, updated_at: "2026-07-19T10:00:00.000Z" };
    const merged = mergeRepoRuns(store, "acme/app", [newer], "2026-07-19T11:00:00.000Z");
    expect(merged.map((run) => run.id)).toEqual([2, 1]);
    expect(recentRepoRuns(store, "acme/app", 1).map((run) => run.id)).toEqual([2]);
  });

  test("persists and reloads from disk", () => {
    dir = mkdtempSync(join(tmpdir(), "overdeck-run-history-"));
    process.env.OVERDECK_STATE_DIR = dir;
    const path = join(dir, "ghci-run-history.json");
    const store = {};
    mergeRepoRuns(store, "acme/app", [baseRun], "2026-07-19T10:00:00.000Z");
    writeRunHistory(store, path);
    expect(readRunHistory(path)["acme/app"]?.runs).toHaveLength(1);
  });
});
