import { readFileSync } from "node:fs";
import { describe, expect, test } from "bun:test";
import {
  DEFAULT_REMOTE_CONFIG,
  isBuildRemoteDisabled,
  parseBuildRemoteConfig,
  safeParseBuildRemoteConfig,
} from "./config-schema";

describe("config-schema", () => {
  test("rejects unknown keys", () => {
    const parsed = safeParseBuildRemoteConfig({ enabled: true, mystery: true });
    expect(parsed.success).toBe(false);
  });

  test("fills every pinned default when fields are omitted", () => {
    const config = parseBuildRemoteConfig({});
    expect(config).toEqual(DEFAULT_REMOTE_CONFIG);
    expect(config.push_excludes).toEqual(DEFAULT_REMOTE_CONFIG.push_excludes);
    expect(config.pull_excludes).toEqual(DEFAULT_REMOTE_CONFIG.pull_excludes);
  });

  test("preserves validated overrides", () => {
    const config = parseBuildRemoteConfig({
      enabled: true,
      port: 2222,
      identity_file: "~/.ssh/id_ed25519_buildbox",
      dispatch_timeout_sec: 45,
      rsync_timeout_sec: 300,
      doctor_host_timeout_sec: 10,
      local_step_timeout_sec: 30,
      remote_wait_sec: 15,
      remote_job_timeout_sec: 7200,
      ship_ignored: [".dev.vars", ".env", ".env.local", ".dev.vars.ci"],
    });
    expect(config.port).toBe(2222);
    expect(config.identity_file).toBe("~/.ssh/id_ed25519_buildbox");
    expect(config.dispatch_timeout_sec).toBe(45);
    expect(config.rsync_timeout_sec).toBe(300);
    expect(config.doctor_host_timeout_sec).toBe(10);
    expect(config.local_step_timeout_sec).toBe(30);
    expect(config.remote_wait_sec).toBe(15);
    expect(config.remote_job_timeout_sec).toBe(7200);
    expect(config.ship_ignored).toEqual([".dev.vars", ".env", ".env.local", ".dev.vars.ci"]);
  });

  test("preserves validated k3s overrides", () => {
    const config = parseBuildRemoteConfig({
      k3s_enabled: true,
      k3s_allowlist: ["pnpm"],
      k3s_image: "registry.example/build:1",
      k3s_namespace: "overdeck-builds",
      k3s_service_account: "overdeck-builder",
      k3s_kubeconfig: "/run/user/1000/k3s.yaml",
      k3s_api_server: "https://127.0.0.1:6443",
      k3s_ca_sha256: "a".repeat(64),
    });
    expect(config.k3s_enabled).toBe(true);
    expect(config.k3s_allowlist).toEqual(["pnpm"]);
    expect(config.k3s_image).toBe("registry.example/build:1");
    expect(config.k3s_namespace).toBe("overdeck-builds");
    expect(config.k3s_service_account).toBe("overdeck-builder");
    expect(config.k3s_kubeconfig).toBe("/run/user/1000/k3s.yaml");
    expect(config.k3s_api_server).toBe("https://127.0.0.1:6443");
    expect(config.k3s_ca_sha256).toBe("a".repeat(64));
  });

  test("rejects malformed k3s CA fingerprints", () => {
    const parsed = safeParseBuildRemoteConfig({ k3s_ca_sha256: "not-a-sha256" });
    expect(parsed.success).toBe(false);
  });

  test("reports the remote job timeout without enforcing it", () => {
    const source = readFileSync(new URL("../../modules/workstation/claude/lib/remote-build.mjs", import.meta.url), "utf8");
    const uses = source.split("remote_job_timeout_sec").length - 1;
    expect(uses).toBe(1);
    expect(source).toContain("timeoutSec: Number(cfg.remote_job_timeout_sec)");
    expect(source).not.toContain("remoteJobTimeoutSec");
    expect(source).not.toContain("RuntimeMaxSec");
  });

  test("refuses a leftover hosts key", () => {
    const parsed = safeParseBuildRemoteConfig({ enabled: true, hosts: ["debian1"] });
    expect(parsed.success).toBe(false);
  });

  test("refuses a legacy host key", () => {
    const parsed = safeParseBuildRemoteConfig({ enabled: true, host: "debian1" });
    expect(parsed.success).toBe(false);
  });

  test("leaves hosts empty for a tuning-only config", () => {
    const config = parseBuildRemoteConfig({
      enabled: true,
      port: 2222,
      ssh_user: "user",
      identity_file: "~/.ssh/id_ed25519_buildbox",
    });
    expect(config.hosts).toEqual([]);
    expect(isBuildRemoteDisabled(config)).toBe(true);
  });

  test("an enabled config is live once the caller injects fleet hosts", () => {
    const config = { ...parseBuildRemoteConfig({ enabled: true, port: 2222 }), hosts: ["debian1"] };
    expect(isBuildRemoteDisabled(config)).toBe(false);
  });

  test("the fleet declaration is the host source remote-build injects", () => {
    const source = readFileSync(new URL("../../modules/workstation/claude/lib/remote-build.mjs", import.meta.url), "utf8");
    expect(source).toContain("registryBuildHosts");
    expect(source).toContain("loadFleet");
  });
});
