import { describe, expect, test } from "bun:test";
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { hostFactsFor, hostsRegistryPath, readHostRegistry } from "./hosts";

const REGISTRY = JSON.stringify({
  schema_version: 1,
  hosts: [
    { name: "debian1", ssh_alias: "debian1", state: "reachable", machine_id: "abc", roles: ["builder"], notes: "kvm" },
    { name: "debian3", ssh_alias: "debian3", state: "bricked", machine_id: null, roles: ["builder"], notes: "bricked" },
  ],
  orders: { build: ["debian1"] },
});

describe("host registry", () => {
  test("reads declared enablement without contacting any host", () => {
    const result = readHostRegistry("/registry.json", () => REGISTRY);
    expect(result.missing).toBe(false);
    expect(result.hosts).toEqual([
      { name: "debian1", reachability: "declared-enabled", state: "reachable", notes: "kvm" },
      { name: "debian3", reachability: "declared-disabled", state: "bricked", notes: "bricked" },
    ]);
  });

  test("reads the registry the workstation module actually ships, extra keys and all", () => {
    const real = readHostRegistry("/real.json", () => readFileSync(
      join(import.meta.dir, "../../../modules/workstation/claude/buildbox-hosts.json"),
      "utf8",
    ));
    expect(real.missing).toBe(false);
    expect(real.hosts.length).toBeGreaterThan(0);
    for (const host of real.hosts) expect(host.state).not.toBeNull();
  });

  test("an unreadable or malformed registry reads as missing rather than throwing", () => {
    expect(readHostRegistry("/gone.json", () => { throw new Error("ENOENT"); })).toEqual({ hosts: [], missing: true });
    expect(readHostRegistry("/bad.json", () => "{not json")).toEqual({ hosts: [], missing: true });
    expect(readHostRegistry("/v2.json", () => JSON.stringify({ schema_version: 2, hosts: [] }))).toEqual({ hosts: [], missing: true });
  });

  test("a host outside the registry is unknown, never assumed reachable", () => {
    const snapshot = { localHost: "e14", hosts: readHostRegistry("/r", () => REGISTRY).hosts, path: "/r", missing: false };
    expect(hostFactsFor(snapshot, "debian1")?.reachability).toBe("declared-enabled");
    expect(hostFactsFor(snapshot, "debian9")).toEqual({ name: "debian9", reachability: "unknown", state: null, notes: null });
    expect(hostFactsFor(snapshot, null)).toBeNull();
  });

  test("the registry path honours the same env override as the workstation reader", () => {
    expect(hostsRegistryPath({ BUILDBOX_HOSTS_CONFIG: "/tmp/hosts.json" })).toBe("/tmp/hosts.json");
    expect(hostsRegistryPath({ HOME: "/home/user" })).toBe("/home/user/.claude/buildbox-hosts.json");
  });
});
