import { existsSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
import { isRecord } from "../utils.js";
import { getSourcesConfigPath } from "./source-config.js";
function notFoundError(resourceId) {
    return new Error(`Source resourceId ${JSON.stringify(resourceId)} not found in sources config`);
}
function parseConfigRootOrThrow(filePath, raw) {
    try {
        return JSON.parse(raw);
    }
    catch (e) {
        const msg = e instanceof Error ? e.message : String(e);
        throw new Error(`Failed to parse sources config at ${filePath}: ${msg}`);
    }
}
function getWorkingArray(root) {
    if (Array.isArray(root)) {
        return { workingArray: root, root };
    }
    if (isRecord(root) && Array.isArray(root.sources)) {
        return { workingArray: root.sources, root };
    }
    throw new Error('Invalid sources config: root must be a JSON array of sources, or an object with a "sources" array');
}
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 mutateConfigFilePath(path, resourceId, mutate) {
    if (!existsSync(path)) {
        throw notFoundError(resourceId);
    }
    const root = parseConfigRootOrThrow(path, readFileSync(path, "utf8"));
    const { workingArray } = getWorkingArray(root);
    const index = findFirstIndexByResourceId(workingArray, resourceId);
    if (index < 0) {
        throw notFoundError(resourceId);
    }
    mutate(workingArray, index);
    writeAtomicFile(path, root);
}
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;
}
export function pauseSourceInConfigFile(path, resourceId) {
    mutateConfigFilePath(path, resourceId, (workingArray, index) => {
        const entry = workingArray[index];
        if (!isRecord(entry)) {
            throw notFoundError(resourceId);
        }
        workingArray[index] = { ...entry, disabled: true };
    });
}
export function resumeSourceInConfigFile(path, resourceId) {
    mutateConfigFilePath(path, resourceId, (workingArray, index) => {
        const entry = workingArray[index];
        if (!isRecord(entry)) {
            throw notFoundError(resourceId);
        }
        const next = { ...entry };
        delete next.disabled;
        workingArray[index] = next;
    });
}
export function removeSourceInConfigFile(path, resourceId) {
    mutateConfigFilePath(path, resourceId, (workingArray, index) => {
        workingArray.splice(index, 1);
    });
}
export function pauseSourceInConfig(cwd, resourceId) {
    pauseSourceInConfigFile(getSourcesConfigPath(cwd), resourceId);
}
export function resumeSourceInConfig(cwd, resourceId) {
    resumeSourceInConfigFile(getSourcesConfigPath(cwd), resourceId);
}
export function removeSourceInConfig(cwd, resourceId) {
    removeSourceInConfigFile(getSourcesConfigPath(cwd), resourceId);
}
//# sourceMappingURL=source-config-writer.js.map