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

// Docker container đã tồn tại — AM start/stop, đọc log, lấy version qua `docker exec`.
// `ref` = tên container (vd "opencode-main"). Dùng `docker inspect` để check trạng thái.

export const dockerStrategy: DeployStrategy = {
  async status({ hostId, ref, versionProbe }) {
    const inspect = await exec(
      hostId,
      `docker inspect -f '{{.State.Running}}|{{.State.Pid}}|{{.State.Status}}|{{.Image}}|{{.State.StartedAt}}|{{.RestartCount}}' ${ref}`,
    );
    if (!inspect.ok) {
      return { ok: false, log: `docker inspect ${ref} failed:\n${inspect.stderr || inspect.stdout}`, running: false };
    }
    const [running, pid, state, image, startedAt, rc] = inspect.stdout.trim().split("|");
    const v = await exec(hostId, `docker exec ${ref} sh -lc ${JSON.stringify(versionProbe)} 2>/dev/null || ${versionProbe}`);
    const cleanV = v.ok && v.stdout.trim() && !/command not found|No such file/i.test(v.stdout)
      ? v.stdout.trim() : undefined;
    const restartCount = parseInt(rc || "0", 10) || 0;
    let uptimeSec = 0;
    if (running === "true" && startedAt) {
      const startedMs = Date.parse(startedAt);
      if (!isNaN(startedMs)) uptimeSec = Math.max(0, Math.floor((Date.now() - startedMs) / 1000));
    }
    return {
      ok: true,
      log: `container: ${ref}\nimage: ${image}\nstate: ${state}\nrunning: ${running}\npid: ${pid}\nversion: ${cleanV || "-"}\nuptime: ${uptimeSec}s\nrestarts: ${restartCount}`,
      version: cleanV,
      running: running === "true",
      pid: running === "true" ? parseInt(pid, 10) || undefined : undefined,
      uptimeSec: running === "true" ? uptimeSec : undefined,
      restartCount,
    };
  },

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

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

  async restart({ hostId, ref }) {
    const r = await exec(hostId, `docker restart ${ref}`, { timeoutMs: 30_000 });
    return { ok: r.ok, log: fmtExec(`docker restart ${ref}`, r) };
  },

  async logs({ hostId, ref }, lines = 200) {
    const r = await exec(hostId, `docker logs --tail ${lines} ${ref} 2>&1`, { timeoutMs: 15_000 });
    return { ok: r.ok, log: r.stdout || r.stderr };
  },

  async uninstall({ hostId, ref }) {
    const r = await exec(hostId, `docker rm -f ${ref}`);
    return { ok: r.ok, log: fmtExec(`docker rm -f ${ref}`, r) };
  },
};
