"use strict";

/**
 * openclaw health [--full]
 *
 * Performs health checks on the OpenClaw installation.
 */

const fs = require("fs");
const path = require("path");
const { execSync } = require("child_process");
const http = require("http");

const CONFIG_FILE = "/etc/openclaw/config.json";
const TOKEN_FILE = "/etc/openclaw/token";
const WORKSPACE_META = "/var/lib/openclaw/.workspace.json";
const MCP_STATE_FILE = "/etc/openclaw/mcp-state.json";

function checkConfig() {
  process.stdout.write("  Configuration: ");
  if (!fs.existsSync(CONFIG_FILE)) {
    console.log("FAIL (not found)");
    return false;
  }
  try {
    JSON.parse(fs.readFileSync(CONFIG_FILE, "utf8"));
    console.log("OK");
    return true;
  } catch {
    console.log("FAIL (invalid JSON)");
    return false;
  }
}

function checkToken() {
  process.stdout.write("  Token: ");
  if (!fs.existsSync(TOKEN_FILE)) {
    console.log("FAIL (not found)");
    return false;
  }
  const token = fs.readFileSync(TOKEN_FILE, "utf8").trim();
  if (token.length < 10) {
    console.log("FAIL (too short)");
    return false;
  }
  console.log("OK");
  return true;
}

function checkWorkspace() {
  process.stdout.write("  Workspace: ");
  if (!fs.existsSync(WORKSPACE_META)) {
    console.log("FAIL (not initialized)");
    return false;
  }
  const requiredDirs = [
    "/var/lib/openclaw/models",
    "/var/lib/openclaw/data",
    "/var/lib/openclaw/cache",
  ];
  for (const dir of requiredDirs) {
    if (!fs.existsSync(dir)) {
      console.log(`FAIL (missing ${dir})`);
      return false;
    }
  }
  console.log("OK");
  return true;
}

function checkService(serviceName) {
  process.stdout.write(`  ${serviceName}: `);
  try {
    const status = execSync(`systemctl is-active ${serviceName}`, {
      encoding: "utf8",
    }).trim();
    console.log(status);
    return status === "active";
  } catch {
    console.log("inactive");
    return false;
  }
}

function checkPort(port, label) {
  return new Promise((resolve) => {
    process.stdout.write(`  ${label} (port ${port}): `);
    const req = http.request(
      { host: "127.0.0.1", port: port, path: "/health", timeout: 3000 },
      (res) => {
        console.log(`OK (HTTP ${res.statusCode})`);
        res.resume();
        resolve(true);
      }
    );
    req.on("error", () => {
      console.log("FAIL (not reachable)");
      resolve(false);
    });
    req.on("timeout", () => {
      req.destroy();
      console.log("FAIL (timeout)");
      resolve(false);
    });
    req.end();
  });
}

function checkMcp() {
  process.stdout.write("  MCP: ");
  if (!fs.existsSync(MCP_STATE_FILE)) {
    console.log("not connected");
    return false;
  }
  const state = JSON.parse(fs.readFileSync(MCP_STATE_FILE, "utf8"));
  console.log(state.status || "unknown");
  return state.status === "connected";
}

function checkLogs() {
  process.stdout.write("  Log directory: ");
  const logDir = "/var/log/openclaw";
  if (!fs.existsSync(logDir)) {
    console.log("FAIL (not found)");
    return false;
  }
  console.log("OK");
  return true;
}

async function run(args) {
  const full = args.includes("--full");

  console.log("OpenClaw Health Check");
  console.log("=====================");
  console.log("");

  let allOk = true;

  // Basic checks
  if (!checkConfig()) allOk = false;
  if (!checkToken()) allOk = false;
  if (!checkWorkspace()) allOk = false;
  if (!checkLogs()) allOk = false;

  if (full) {
    console.log("");
    console.log("Service Status:");

    if (!checkService("openclaw.service")) allOk = false;
    if (!checkService("openclaw-gateway.service")) allOk = false;

    console.log("");
    console.log("Connectivity:");

    let config;
    try {
      config = JSON.parse(fs.readFileSync(CONFIG_FILE, "utf8"));
    } catch {
      config = { server: { port: 3100 }, gateway: { port: 3200 } };
    }

    const serverOk = await checkPort(config.server?.port || 3100, "Server");
    const gatewayOk = await checkPort(config.gateway?.port || 3200, "Gateway");
    if (!serverOk || !gatewayOk) allOk = false;

    console.log("");
    console.log("Knowledge Base:");
    checkMcp();
  }

  console.log("");
  if (allOk) {
    console.log("Result: ALL CHECKS PASSED");
  } else {
    console.log("Result: SOME CHECKS FAILED");
    process.exit(1);
  }
}

module.exports = { run };
