import { spawn } from "node:child_process";
import { access, writeFile } from "node:fs/promises";
import { constants } from "node:fs";
import { join } from "node:path";
/**
 * Intégration Caddy (reverse proxy + HTTPS automatique Let's Encrypt).
 *
 * L'assistant de premier lancement génère un Caddyfile pour le domaine choisi
 * et tente de l'appliquer : reload du service systemd sur Linux, sinon
 * `caddy reload` direct. Si aucun binaire/service n'est disponible, le
 * Caddyfile reste écrit (emplacement standard ou dossier de données) — c'est
 * l'utilisateur qui recharge Caddy plus tard.
 *
 * Aucune donnée ne passe par un tiers : Caddy tourne sur la même machine que
 * le serveur et ne sert que de front HTTPS.
 */
export function renderCaddyfile(domain, port) {
    return `${domain} {
	encode zstd gzip
	reverse_proxy 127.0.0.1:${port}
}
`;
}
async function isWritable(path) {
    try {
        await access(path, constants.W_OK);
        return true;
    }
    catch {
        return false;
    }
}
/**
 * Emplacement du Caddyfile : /etc/caddy/Caddyfile quand on a les droits
 * (Linux, installation système), sinon DATA_DIR/Caddyfile.
 */
export async function caddyfilePath(dataDir) {
    if (process.platform === "linux" && (await isWritable("/etc/caddy/Caddyfile"))) {
        return "/etc/caddy/Caddyfile";
    }
    return join(dataDir, "Caddyfile");
}
/** Écrit le Caddyfile au bon endroit et renvoie son chemin. */
export async function writeCaddyfile(domain, port, dataDir) {
    const path = await caddyfilePath(dataDir);
    await writeFile(path, renderCaddyfile(domain, port), "utf8");
    return path;
}
function run(command, args) {
    return new Promise((resolve) => {
        const child = spawn(command, args, { stdio: ["ignore", "ignore", "pipe"] });
        let stderr = "";
        child.stderr.on("data", (d) => {
            stderr += d.toString();
        });
        const timer = setTimeout(() => {
            child.kill();
            resolve({ ok: false, stderr: `timeout (${command})` });
        }, 10_000);
        child.on("error", (err) => {
            clearTimeout(timer);
            resolve({ ok: false, stderr: err.message });
        });
        child.on("exit", (code) => {
            clearTimeout(timer);
            resolve({ ok: code === 0, stderr });
        });
    });
}
/**
 * Tente d'appliquer le Caddyfile. Priorité au service systemd (reload à
 * chaud, sans couper le trafic), sinon `caddy reload`. Renvoie la méthode
 * employée, ou un échec avec le message à transmettre à l'utilisateur.
 */
export async function applyCaddy(caddyfile) {
    if (process.platform === "linux") {
        const sys = await run("systemctl", ["reload", "caddy"]);
        if (sys.ok)
            return { ok: true, action: "systemctl reload caddy" };
    }
    const direct = await run("caddy", ["reload", "--config", caddyfile]);
    if (direct.ok) {
        return { ok: true, action: `caddy reload --config ${caddyfile}` };
    }
    return { ok: false, action: direct.stderr.split("\n")[0] ?? "binaire caddy introuvable" };
}
//# sourceMappingURL=caddy.js.map