import { sshExec } from "../utils/ssh.js";
import { getErrorMessage, mapSshError, sanitizeStderr } from "../utils/errorMapper.js";
import { cmd, raw } from "../utils/sshCommand.js";
const EMPTY_METRICS = {
    cpu: "N/A",
    ramUsed: "N/A",
    ramTotal: "N/A",
    diskUsed: "N/A",
    diskTotal: "N/A",
    diskPercent: "N/A",
};
export function buildLogCommand(service, lines, follow = false) {
    const safeLines = Math.max(1, Math.min(500, Math.floor(lines)));
    switch (service) {
        case "coolify":
            // safeLines is a clamped integer — safe to use with cmd()
            return follow
                ? cmd("docker", "logs", "coolify", "--tail", String(safeLines), "--follow")
                : cmd("docker", "logs", "coolify", "--tail", String(safeLines));
        case "dokploy":
            return follow
                ? cmd("docker", "service", "logs", "dokploy_dokploy", "--tail", String(safeLines), "--follow")
                : cmd("docker", "service", "logs", "dokploy_dokploy", "--tail", String(safeLines));
        case "docker":
            return follow
                ? cmd("journalctl", "-u", "docker", "--no-pager", "-n", String(safeLines), "-f")
                : cmd("journalctl", "-u", "docker", "--no-pager", "-n", String(safeLines));
        case "system":
            return follow
                ? cmd("journalctl", "--no-pager", "-n", String(safeLines), "-f")
                : cmd("journalctl", "--no-pager", "-n", String(safeLines));
    }
}
export function buildMonitorCommand(includeContainers) {
    let command = "LANG=C LC_ALL=C top -bn1 | head -5 && echo '---SEPARATOR---' && LANG=C LC_ALL=C free -h && echo '---SEPARATOR---' && LANG=C LC_ALL=C df -h --total | grep -E '(Filesystem|total)'";
    if (includeContainers) {
        command +=
            " && echo '---SEPARATOR---' && (docker ps --format 'table {{.Names}}\\t{{.Status}}\\t{{.Ports}}' 2>/dev/null || echo 'Docker not installed')";
    }
    return raw(command);
}
export function parseMetrics(stdout) {
    const lines = stdout.split("\n");
    let cpu = "N/A";
    for (const line of lines) {
        if (line.includes("Cpu") || line.includes("cpu")) {
            const idleMatch = line.match(/([\d.]+)\s*(?:%?\s*)?id/);
            if (idleMatch) {
                const idle = parseFloat(idleMatch[1]);
                cpu = `${(100 - idle).toFixed(1)}%`;
            }
            break;
        }
    }
    let ramUsed = "N/A";
    let ramTotal = "N/A";
    for (const line of lines) {
        if (line.startsWith("Mem:")) {
            const parts = line.split(/\s+/);
            if (parts.length >= 3) {
                ramTotal = parts[1];
                ramUsed = parts[2];
            }
            break;
        }
    }
    let diskUsed = "N/A";
    let diskTotal = "N/A";
    let diskPercent = "N/A";
    for (const line of lines) {
        if (line.startsWith("total") || line.includes("/dev/")) {
            const parts = line.split(/\s+/);
            if (parts.length >= 5) {
                diskTotal = parts[1];
                diskUsed = parts[2];
                diskPercent = parts[4];
            }
            if (line.startsWith("total"))
                break;
        }
    }
    return { cpu, ramUsed, ramTotal, diskUsed, diskTotal, diskPercent };
}
export async function fetchServerLogs(ip, service, lines) {
    try {
        const command = buildLogCommand(service, lines, false);
        const result = await sshExec(ip, command);
        if (result.code !== 0) {
            const hint = mapSshError(new Error(result.stderr || "SSH command failed"), ip);
            return {
                logs: result.stdout || "",
                service,
                lines,
                error: sanitizeStderr(result.stderr) || `Exit code ${result.code}`,
                ...(hint ? { hint } : {}),
            };
        }
        return { logs: result.stdout, service, lines };
    }
    catch (error) {
        const hint = mapSshError(error, ip);
        return {
            logs: "",
            service,
            lines,
            error: getErrorMessage(error),
            ...(hint ? { hint } : {}),
        };
    }
}
export async function fetchServerMetrics(ip, includeContainers) {
    try {
        const command = buildMonitorCommand(includeContainers);
        const result = await sshExec(ip, command);
        if (result.code !== 0) {
            const hint = mapSshError(new Error(result.stderr || "SSH command failed"), ip);
            return {
                metrics: { ...EMPTY_METRICS },
                error: sanitizeStderr(result.stderr) || `Exit code ${result.code}`,
                ...(hint ? { hint } : {}),
            };
        }
        const metrics = parseMetrics(result.stdout);
        let containers;
        if (includeContainers) {
            const sections = result.stdout.split("---SEPARATOR---");
            if (sections.length >= 4) {
                containers = sections[3].trim();
            }
        }
        return { metrics, ...(containers ? { containers } : {}) };
    }
    catch (error) {
        const hint = mapSshError(error, ip);
        return {
            metrics: { ...EMPTY_METRICS },
            error: getErrorMessage(error),
            ...(hint ? { hint } : {}),
        };
    }
}
//# sourceMappingURL=logs.js.map