/**
 * PR-A Baseline Test 01: Gateway Startup
 * Verifies: gateway process is running and reachable
 * Freezes: gateway startup contract
 */
import { describe, it } from "node:test";
import assert from "node:assert";
import { execSync } from "node:child_process";
import { request } from "node:http";
import { readFileSync } from "node:fs";
import { homedir } from "node:os";
import { join } from "node:path";

const AGENTS_HOME = join(homedir(), ".openclaw");
let _config, _port;

function loadConfig() {
  if (!_config) {
    _config = JSON.parse(readFileSync(join(AGENTS_HOME, "openclaw.json"), "utf8"));
    _port = _config?.gateway?.port || 18789;
  }
  return { config: _config, gatewayPort: _port };
}

function httpGet(host, port, path) {
  return new Promise((resolve, reject) => {
    const req = request({ hostname: host, port, path, method: "GET", timeout: 10000 }, (res) => {
      let body = "";
      res.on("data", (d) => (body += d));
      res.on("end", () => resolve({ status: res.statusCode, body }));
    });
    req.on("error", reject);
    req.on("timeout", () => { req.destroy(); reject(new Error("timeout")); });
    req.end();
  });
}

describe("test-01: Gateway Startup Baseline", () => {
  it("01.01 - gateway config exists", () => {
    const { config } = loadConfig();
    assert.ok(config, "config should be loaded");
    assert.ok(config.gateway, "gateway section should exist");
  });

  it("01.02 - gateway bind port is defined", () => {
    const { gatewayPort } = loadConfig();
    assert.ok(gatewayPort > 0 && gatewayPort < 65536, `port ${gatewayPort} must be valid`);
  });

  it("01.03 - gateway is reachable via HTTP", async () => {
    const { gatewayPort } = loadConfig();
    const result = await httpGet("127.0.0.1", gatewayPort, "/");
    assert.ok(result.status >= 200 && result.status < 400,
      `gateway HTTP must respond with 2xx/3xx, got ${result.status}`);
  });

  it("01.04 - gateway status reports running", () => {
    const out = execSync("openclaw status --json 2>/dev/null", { timeout: 15000, encoding: "utf8" }).trim();
    assert.ok(out.length > 0, "openclaw status must produce output");
    try {
      const s = JSON.parse(out);
      assert.ok(s, "status must be valid JSON");
    } catch {
      assert.ok(!out.toLowerCase().includes("error"), "status must not report error");
    }
  });

  it("01.05 - gateway process is not crashing (baseline snapshot)", () => {
    const out = execSync("openclaw status 2>&1", { timeout: 15000, encoding: "utf8" }).trim();
    const isRunning = out.includes("running") || out.includes("active") || out.includes("reachable");
    console.log("[BASELINE] gateway status snapshot:", out.substring(0, 300));
    assert.ok(isRunning, "gateway must be running");
  });

  it("01.06 - memory index is accessible", () => {
    const out = execSync("openclaw memory status --json 2>/dev/null", { timeout: 15000, encoding: "utf8" }).trim();
    const s = JSON.parse(out);
    assert.ok(Array.isArray(s) && s.length > 0, "at least one agent memory entry");
    const main = s.find((e) => e.agentId === "main");
    assert.ok(main, "main agent must have memory");
    console.log("[BASELINE] memory backend: %s, files: %d, chunks: %d",
      main.status.backend, main.status.files, main.status.chunks);
  });

  it("01.07 - gateway auth mode recorded", () => {
    const { config } = loadConfig();
    const mode = config?.gateway?.auth?.mode;
    console.log("[BASELINE] gateway auth mode:", mode);
    assert.ok(mode, "gateway auth mode must be defined");
  });
});
