import { existsSync, readFileSync } from "node:fs";
import path from "node:path";
import { restartLocalDaemon, resolveLocalDaemonSnapshot, startLocalDaemon, stopLocalDaemon, } from "./local-daemon-control.js";
import { readConfigListen, resolvePaseoHome } from "./paseo-home.js";
import { resolveTailscaleIpv4 } from "./tailscale.js";
function healthUrlFromListen(listen) {
    const normalized = listen.replace(/^https?:\/\//, "");
    const host = normalized.startsWith("0.0.0.0")
        ? normalized.replace("0.0.0.0", "127.0.0.1")
        : normalized;
    return `http://${host}/api/health`;
}
function webUiUrlFromListen(listen) {
    if (listen.includes("/") && !listen.includes(":")) {
        return null;
    }
    const normalized = listen.replace(/^https?:\/\//, "");
    const host = normalized.startsWith("0.0.0.0")
        ? normalized.replace("0.0.0.0", "127.0.0.1")
        : normalized;
    return `http://${host}`;
}
async function probeHealth(listen) {
    const url = healthUrlFromListen(listen);
    try {
        const response = await fetch(url, { signal: AbortSignal.timeout(3000) });
        return { ok: response.ok, statusCode: response.status, url };
    }
    catch {
        return { ok: false, statusCode: null, url };
    }
}
function buildDaemonStatus(snapshot, health) {
    let localDaemon = snapshot.running ? "running" : "stopped";
    let note;
    if (snapshot.stalePidFile && snapshot.pidInfo) {
        localDaemon = "stale_pid";
        note = `Stale PID file found for PID ${snapshot.pidInfo.pid}`;
    }
    else if (snapshot.running && !health.ok) {
        localDaemon = "unresponsive";
        note = "Process is running but API health check failed";
    }
    return {
        serverId: snapshot.serverId,
        localDaemon,
        connectedDaemon: health.ok ? "reachable" : snapshot.running ? "unreachable" : "not_probed",
        home: snapshot.home,
        listen: snapshot.listen,
        relay: snapshot.relayEnabled ? "enabled" : "disabled",
        hostname: snapshot.pidInfo?.hostname ?? null,
        pid: snapshot.pidInfo?.pid ?? null,
        startedAt: snapshot.pidInfo?.startedAt ?? null,
        logPath: snapshot.logPath,
        daemonVersion: null,
        runningAgents: null,
        idleAgents: null,
        note,
    };
}
export async function getManagerStatus() {
    const home = resolvePaseoHome();
    const configListen = readConfigListen(home);
    const tailscale = await resolveTailscaleIpv4();
    try {
        const snapshot = resolveLocalDaemonSnapshot();
        const listen = snapshot.listen;
        const health = await probeHealth(listen);
        const daemon = buildDaemonStatus(snapshot, health);
        return {
            daemon,
            health,
            tailscale,
            configListen,
            webUiUrl: health.ok ? webUiUrlFromListen(listen) : null,
            error: null,
        };
    }
    catch (error) {
        const listen = configListen ?? process.env.PASEO_LISTEN?.trim() ?? "0.0.0.0:6769";
        const health = await probeHealth(listen);
        return {
            daemon: null,
            health,
            tailscale,
            configListen,
            webUiUrl: health.ok ? webUiUrlFromListen(listen) : null,
            error: error instanceof Error ? error.message : String(error),
        };
    }
}
export async function startDaemon() {
    return startLocalDaemon();
}
export async function stopDaemon() {
    return stopLocalDaemon();
}
export async function restartDaemon() {
    return restartLocalDaemon();
}
export function readDaemonLogs(tailLines = 250) {
    const home = resolvePaseoHome();
    const logPath = path.join(home, "daemon.log");
    if (!existsSync(logPath)) {
        return { logPath, contents: "" };
    }
    const raw = readFileSync(logPath, "utf8");
    const lines = raw.split(/\r?\n/);
    return { logPath, contents: lines.slice(-tailLines).join("\n") };
}
