import { exec } from "../ssh";
import type { DeployStrategy } from "./types";
import { fmtExec } from "./types";

export const systemdStrategy: DeployStrategy = {
  async status({ hostId, ref, versionProbe }) {
    const v = await exec(hostId, versionProbe);
    const s = await exec(
      hostId,
      `systemctl is-active ${ref} 2>/dev/null; systemctl show ${ref} -p MainPID,ActiveEnterTimestampMonotonic,NRestarts --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 activeMonotonicUs = parseInt(lines[2] || "0", 10) || 0;
    const restartCount = parseInt(lines[3] || "0", 10) || 0;
    // ActiveEnterTimestampMonotonic là microseconds từ boot. Cần lấy current monotonic time.
    let uptimeSec = 0;
    if (active && activeMonotonicUs > 0) {
      const m = await exec(hostId, `awk '{print int($1)}' /proc/uptime`);
      const bootSec = parseInt(m.stdout.trim() || "0", 10);
      const enteredSec = Math.floor(activeMonotonicUs / 1_000_000);
      uptimeSec = Math.max(0, bootSec - enteredSec);
    }
    const cleanV = v.ok && v.stdout.trim() && !/command not found|No such file/i.test(v.stdout)
      ? v.stdout.trim() : undefined;
    return {
      ok: true,
      log: `version: ${cleanV || "-"}\nunit: ${lines[0] || "(missing)"}\npid: ${pid ?? "-"}\nuptime: ${uptimeSec}s\nrestarts: ${restartCount}`,
      version: cleanV,
      running: active,
      pid: active ? pid : undefined,
      uptimeSec: active ? uptimeSec : undefined,
      restartCount,
    };
  },

  async start({ hostId, ref }) {
    const r = await exec(hostId, `systemctl start ${ref} && systemctl is-active ${ref}`);
    return { ok: r.ok, log: fmtExec(`systemctl start ${ref}`, r) };
  },

  async stop({ hostId, ref }) {
    const r = await exec(hostId, `systemctl stop ${ref}`);
    return { ok: r.ok, log: fmtExec(`systemctl stop ${ref}`, r) };
  },

  async restart({ hostId, ref }) {
    const r = await exec(hostId, `systemctl restart ${ref} && systemctl is-active ${ref}`);
    return { ok: r.ok, log: fmtExec(`systemctl restart ${ref}`, r) };
  },

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

  async uninstall({ hostId, ref }) {
    const r = await exec(
      hostId,
      `systemctl disable --now ${ref} 2>/dev/null || true; rm -f /etc/systemd/system/${ref}; systemctl daemon-reload`,
    );
    return { ok: true, log: fmtExec(`uninstall systemd ${ref}`, r) };
  },
};
