function systemdEscapeArg(value) {
    if (!/[\\s"\\\\]/.test(value))
        return value;
    return `"${value.replace(/\\\\/g, "\\\\\\\\").replace(/"/g, '\\\\"')}"`;
}
function renderEnvLines(env) {
    if (!env)
        return [];
    const entries = Object.entries(env).filter(([, value]) => typeof value === "string" && value.trim());
    if (entries.length === 0)
        return [];
    return entries.map(([key, value]) => `Environment=${systemdEscapeArg(`${key}=${value?.trim() ?? ""}`)}`);
}
export function buildSystemdUnit({ description, programArguments, workingDirectory, environment, }) {
    const execStart = programArguments.map(systemdEscapeArg).join(" ");
    const descriptionLine = `Description=${description?.trim() || "Openclaw Gateway"}`;
    const workingDirLine = workingDirectory
        ? `WorkingDirectory=${systemdEscapeArg(workingDirectory)}`
        : null;
    const envLines = renderEnvLines(environment);
    return [
        "[Unit]",
        descriptionLine,
        "After=network-online.target",
        "Wants=network-online.target",
        "",
        "[Service]",
        `ExecStart=${execStart}`,
        "Restart=always",
        "RestartSec=5",
        // KillMode=process ensures systemd only waits for the main process to exit.
        // Without this, podman's conmon (container monitor) processes block shutdown
        // since they run as children of the gateway and stay in the same cgroup.
        "KillMode=process",
        workingDirLine,
        ...envLines,
        "",
        "[Install]",
        "WantedBy=default.target",
        "",
    ]
        .filter((line) => line !== null)
        .join("\n");
}
export function parseSystemdExecStart(value) {
    const args = [];
    let current = "";
    let inQuotes = false;
    let escapeNext = false;
    for (const char of value) {
        if (escapeNext) {
            current += char;
            escapeNext = false;
            continue;
        }
        if (char === "\\\\") {
            escapeNext = true;
            continue;
        }
        if (char === '"') {
            inQuotes = !inQuotes;
            continue;
        }
        if (!inQuotes && /\s/.test(char)) {
            if (current) {
                args.push(current);
                current = "";
            }
            continue;
        }
        current += char;
    }
    if (current)
        args.push(current);
    return args;
}
export function parseSystemdEnvAssignment(raw) {
    const trimmed = raw.trim();
    if (!trimmed)
        return null;
    const unquoted = (() => {
        if (!(trimmed.startsWith('"') && trimmed.endsWith('"')))
            return trimmed;
        let out = "";
        let escapeNext = false;
        for (const ch of trimmed.slice(1, -1)) {
            if (escapeNext) {
                out += ch;
                escapeNext = false;
                continue;
            }
            if (ch === "\\\\") {
                escapeNext = true;
                continue;
            }
            out += ch;
        }
        return out;
    })();
    const eq = unquoted.indexOf("=");
    if (eq <= 0)
        return null;
    const key = unquoted.slice(0, eq).trim();
    if (!key)
        return null;
    const value = unquoted.slice(eq + 1);
    return { key, value };
}
