import { existsSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
import { isRecord } from "../utils.js";
import { getMcpConfigPath } from "./mcp-config.js";
function notFoundError(resourceId) {
    return `MCP server resourceId ${JSON.stringify(resourceId)} not found in mcp config`;
}
function parseConfigRootOrError(filePath, raw) {
    try {
        return { ok: true, root: JSON.parse(raw) };
    }
    catch (e) {
        const msg = e instanceof Error ? e.message : String(e);
        return { ok: false, error: `Failed to parse mcp config at ${filePath}: ${msg}` };
    }
}
function getWorkingArray(root) {
    if (Array.isArray(root)) {
        return { workingArray: root, root };
    }
    if (isRecord(root)) {
        if (root.servers === undefined) {
            root.servers = [];
        }
        else if (!Array.isArray(root.servers)) {
            throw new Error('Invalid mcp config: "servers" must be an array');
        }
        return { workingArray: root.servers, root };
    }
    throw new Error('Invalid mcp config: root must be a JSON array of servers, or an object with a "servers" array');
}
function findFirstIndexByResourceId(workingArray, resourceId) {
    for (let i = 0; i < workingArray.length; i++) {
        const e = workingArray[i];
        if (isRecord(e) && e.resourceId === resourceId) {
            return i;
        }
    }
    return -1;
}
function writeAtomicFile(path, value) {
    const content = `${JSON.stringify(value, null, 2)}\n`;
    const tmp = `${path}.tmp.${process.pid}.${Date.now()}`;
    try {
        writeFileSync(tmp, content, "utf8");
        renameSync(tmp, path);
    }
    catch (e) {
        try {
            if (existsSync(tmp)) {
                unlinkSync(tmp);
            }
        }
        catch {
            // best-effort cleanup
        }
        throw e;
    }
}
function mutateMcpConfigFile(cwd, resourceId, mutate, configPath = getMcpConfigPath(cwd)) {
    const path = configPath;
    if (!existsSync(path)) {
        return { ok: false, error: notFoundError(resourceId) };
    }
    const parsed = parseConfigRootOrError(path, readFileSync(path, "utf8"));
    if (!parsed.ok) {
        return { ok: false, error: parsed.error };
    }
    const root = parsed.root;
    let workingArray;
    try {
        workingArray = getWorkingArray(root).workingArray;
    }
    catch (e) {
        const msg = e instanceof Error ? e.message : String(e);
        return { ok: false, error: msg };
    }
    const index = findFirstIndexByResourceId(workingArray, resourceId);
    if (index < 0) {
        return { ok: false, error: notFoundError(resourceId) };
    }
    try {
        mutate(workingArray, index);
    }
    catch (e) {
        const msg = e instanceof Error ? e.message : String(e);
        return { ok: false, error: msg };
    }
    try {
        writeAtomicFile(path, root);
    }
    catch (e) {
        const msg = e instanceof Error ? e.message : String(e);
        return { ok: false, error: msg };
    }
    return { ok: true };
}
export function pauseServer(cwd, resourceId, configPath) {
    return mutateMcpConfigFile(cwd, resourceId, (workingArray, index) => {
        const entry = workingArray[index];
        if (!isRecord(entry)) {
            throw new Error(notFoundError(resourceId));
        }
        workingArray[index] = { ...entry, disabled: true };
    }, configPath);
}
// Same choice as `resumeSourceInConfig`: remove the `disabled` key rather than set `false`.
export function restartServer(cwd, resourceId, configPath) {
    return mutateMcpConfigFile(cwd, resourceId, (workingArray, index) => {
        const entry = workingArray[index];
        if (!isRecord(entry)) {
            throw new Error(notFoundError(resourceId));
        }
        const next = { ...entry };
        delete next.disabled;
        workingArray[index] = next;
    }, configPath);
}
export function removeServer(cwd, resourceId, configPath) {
    return mutateMcpConfigFile(cwd, resourceId, (workingArray, index) => {
        workingArray.splice(index, 1);
    }, configPath);
}
//# sourceMappingURL=mcp-config-writer.js.map