import { exec, execScript } from "../ssh";
import type { AgentRunner, AgentRunnerCtx } from "./types";

// Hermes Agent: cài qua install.sh chính thức của NousResearch.
// Mỗi instance = 1 profile riêng (HERMES_PROFILE=<name>).
// Daemon chính là `hermes gateway run` chạy dưới systemd.

function unitName(ctx: AgentRunnerCtx) {
  return `agent-${ctx.name}.service`;
}
function profileName(ctx: AgentRunnerCtx) {
  return ctx.name;
}
function workdir(ctx: AgentRunnerCtx) {
  return `${ctx.installPath}/${ctx.name}`;
}

const SYSTEMD_TEMPLATE = (name: string, wd: string, profile: string) => `
[Unit]
Description=Agent-Manager managed Hermes (${name})
After=network.target

[Service]
Type=simple
WorkingDirectory=${wd}
Environment=HERMES_PROFILE=${profile}
Environment=HOME=/root
ExecStart=/bin/bash -lc 'hermes gateway run'
Restart=on-failure
RestartSec=5
StandardOutput=append:/var/log/agent-${name}.log
StandardError=append:/var/log/agent-${name}.log

[Install]
WantedBy=multi-user.target
`.trim();

export const hermesRunner: AgentRunner = {
  kind: "hermes",

  async install(ctx) {
    const wd = workdir(ctx);
    const unit = unitName(ctx);
    const profile = profileName(ctx);
    const r = await execScript(ctx.hostId, [
      { label: "base deps", cmd: "apt-get update -q 2>&1 | tail -3 && DEBIAN_FRONTEND=noninteractive apt-get install -y -q curl ca-certificates python3 python3-venv git build-essential 2>&1 | tail -3" },
      {
        label: "install hermes",
        cmd:
          "command -v hermes >/dev/null 2>&1 || ls /root/.local/bin/hermes >/dev/null 2>&1 || " +
          "curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash 2>&1 | tail -20",
      },
      { label: "verify binary", cmd: "bash -lc 'hermes --version 2>&1 | head -1' || ls /root/.local/bin/hermes 2>/dev/null" },
      { label: "create profile", cmd: `bash -lc 'hermes profile show ${profile} >/dev/null 2>&1 || hermes profile create ${profile}' 2>&1 | tail -10` },
      { label: "scaffold workdir", cmd: `mkdir -p ${wd}` },
      { label: "write systemd unit", cmd: `cat > /etc/systemd/system/${unit} <<'EOF'\n${SYSTEMD_TEMPLATE(ctx.name, wd, profile)}\nEOF\nsystemctl daemon-reload` },
    ], { timeoutMsPerStep: 600_000 });
    const v = await exec(ctx.hostId, "bash -lc 'hermes --version 2>&1 | head -1'");
    return { ok: r.ok, log: r.log, version: v.stdout.trim() || undefined };
  },

  async update(ctx) {
    const r = await execScript(ctx.hostId, [
      { label: "hermes update", cmd: "bash -lc 'hermes update' 2>&1 | tail -20" },
      { label: "version", cmd: "bash -lc 'hermes --version 2>&1 | head -1'" },
      { label: "restart unit", cmd: `systemctl is-enabled ${unitName(ctx)} >/dev/null 2>&1 && systemctl restart ${unitName(ctx)} || true` },
    ], { timeoutMsPerStep: 600_000 });
    const v = await exec(ctx.hostId, "bash -lc 'hermes --version 2>&1 | head -1'");
    return { ok: r.ok, log: r.log, version: v.stdout.trim() || undefined };
  },

  async status(ctx) {
    const v = await exec(ctx.hostId, "bash -lc 'hermes --version 2>&1 | head -1'");
    const s = await exec(ctx.hostId, `systemctl is-active ${unitName(ctx)} 2>/dev/null; systemctl show ${unitName(ctx)} -p MainPID --value 2>/dev/null`);
    const lines = s.stdout.trim().split("\n");
    const active = lines[0]?.trim() === "active";
    const pid = parseInt(lines[1] || "0", 10) || undefined;
    const gw = await exec(ctx.hostId, `bash -lc 'HERMES_PROFILE=${profileName(ctx)} hermes gateway status 2>&1 | head -10'`);
    return {
      ok: true,
      log: `version: ${v.stdout.trim()}\nunit: ${lines[0]}\npid: ${pid ?? "-"}\n--- gateway ---\n${gw.stdout || gw.stderr}`,
      version: v.stdout.trim() || undefined,
      running: active,
      pid: active ? pid : undefined,
    };
  },

  async start(ctx) {
    const r = await execScript(ctx.hostId, [
      { label: "enable+start", cmd: `systemctl enable --now ${unitName(ctx)}` },
      { label: "status", cmd: `systemctl is-active ${unitName(ctx)}` },
    ]);
    return { ok: r.ok, log: r.log };
  },

  async stop(ctx) {
    const r = await execScript(ctx.hostId, [
      { label: "stop", cmd: `systemctl stop ${unitName(ctx)}` },
    ]);
    return { ok: r.ok, log: r.log };
  },

  async logs(ctx, lines = 200) {
    const r = await exec(ctx.hostId, `tail -n ${lines} /var/log/agent-${ctx.name}.log 2>/dev/null || journalctl -u ${unitName(ctx)} -n ${lines} --no-pager`, { timeoutMs: 15_000 });
    return { ok: true, log: r.stdout || r.stderr };
  },

  async uninstall(ctx) {
    const wd = workdir(ctx);
    const profile = profileName(ctx);
    const r = await execScript(ctx.hostId, [
      { label: "stop+disable", cmd: `systemctl disable --now ${unitName(ctx)} 2>/dev/null || true` },
      { label: "rm unit", cmd: `rm -f /etc/systemd/system/${unitName(ctx)} && systemctl daemon-reload` },
      { label: "delete profile", cmd: `hermes profile delete ${profile} -y 2>&1 | tail -5 || true` },
      { label: "rm workdir", cmd: `rm -rf ${wd}` },
      { label: "rm log", cmd: `rm -f /var/log/agent-${ctx.name}.log` },
    ], { stopOnFail: false });
    return { ok: r.ok, log: r.log };
  },
};
