import { readFileSync, renameSync } from "fs";
import { join } from "path";
import { withFileLock } from "./fileLock.js";
import { KASTELL_DIR } from "./paths.js";
import { SUPPORTED_PROVIDERS } from "../constants.js";
import { secureMkdirSync, secureWriteFileSync } from "./secureWrite.js";
const SERVERS_FILE = join(KASTELL_DIR, "servers.json");
export function getServersRaw() {
    // Same as getServers but without mode default — for migration use only
    const raw = readFileSync(SERVERS_FILE, "utf-8");
    const parsed = JSON.parse(raw);
    if (!Array.isArray(parsed)) {
        throw new Error("servers.json corrupt");
    }
    return parsed;
}
function ensureConfigDir() {
    secureMkdirSync(KASTELL_DIR, { recursive: true });
}
/** Atomic write: write to tmp file, then rename to prevent corruption on crash */
export function atomicWriteServers(servers) {
    const tmpFile = SERVERS_FILE + ".tmp";
    secureWriteFileSync(tmpFile, JSON.stringify(servers, null, 2));
    renameSync(tmpFile, SERVERS_FILE);
}
export function getServers() {
    let data;
    try {
        data = readFileSync(SERVERS_FILE, "utf-8");
    }
    catch (err) {
        if (err.code === "ENOENT") {
            return [];
        }
        throw err;
    }
    let parsed;
    try {
        parsed = JSON.parse(data);
    }
    catch {
        throw new Error("servers.json corrupt (invalid JSON) — check ~/.kastell/servers.json manually");
    }
    if (!Array.isArray(parsed)) {
        throw new Error("servers.json corrupt — check ~/.kastell/servers.json manually");
    }
    const validProviders = new Set(SUPPORTED_PROVIDERS);
    const validRecords = parsed.filter((s) => {
        if (s.provider && !validProviders.has(s.provider)) {
            process.stderr.write(`Warning: skipping server "${s.name}" — unknown provider "${s.provider}"\n`);
            return false;
        }
        return true;
    });
    const servers = validRecords.map((s) => ({ ...s, mode: s.mode ?? "coolify" }));
    return servers;
}
export async function saveServer(record) {
    await withFileLock(SERVERS_FILE, () => {
        ensureConfigDir();
        const servers = getServers();
        const duplicate = servers.find((s) => s.name === record.name || s.ip === record.ip);
        if (duplicate) {
            throw new Error(`Server already exists: ${duplicate.name === record.name ? `name "${record.name}"` : `IP ${record.ip}`}`);
        }
        servers.push(record);
        atomicWriteServers(servers);
    });
}
export async function updateServer(name, updates) {
    return await withFileLock(SERVERS_FILE, () => {
        const servers = getServers();
        const index = servers.findIndex((s) => s.name === name);
        if (index === -1)
            return false;
        servers[index] = { ...servers[index], ...updates };
        ensureConfigDir();
        atomicWriteServers(servers);
        return true;
    });
}
export async function removeServer(id) {
    return await withFileLock(SERVERS_FILE, () => {
        const servers = getServers();
        const filtered = servers.filter((s) => s.id !== id);
        if (filtered.length === servers.length) {
            return false;
        }
        ensureConfigDir();
        atomicWriteServers(filtered);
        return true;
    });
}
export function findServer(query) {
    const servers = getServers();
    // Search by IP first (unique), then by name
    return servers.find((s) => s.ip === query) || servers.find((s) => s.name === query);
}
export function findServers(query) {
    const servers = getServers();
    const byIp = servers.filter((s) => s.ip === query);
    if (byIp.length > 0)
        return byIp;
    return servers.filter((s) => s.name === query);
}
export { BACKUPS_DIR } from "./paths.js";
export { SERVERS_FILE };
//# sourceMappingURL=config.js.map