// @crash-shield-ignore-file — config/cache reader for Planu-controlled JSON; writer is this codebase, shape guaranteed by build/seed.
// Platform registry — loads built-in platforms and merges project-level custom platforms.
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
// === Cache ===
let builtInCache = null;
/** @internal — exported for test resets only */
export function clearPlatformRegistryCache() {
    builtInCache = null;
}
// === Loaders ===
async function loadBuiltInPlatforms() {
    if (builtInCache) {
        return builtInCache;
    }
    try {
        const configPath = new URL('../config/agent-platforms.json', import.meta.url);
        const content = await readFile(configPath, 'utf-8');
        builtInCache = JSON.parse(content);
        return builtInCache;
    }
    catch {
        /* v8 ignore next -- defensive catch for missing config file */
        return { platforms: {} };
    }
}
async function loadCustomPlatforms(projectPath) {
    try {
        const planuJsonPath = join(projectPath, 'planu.json');
        const content = await readFile(planuJsonPath, 'utf-8');
        const parsed = JSON.parse(content);
        return Array.isArray(parsed.customPlatforms) ? parsed.customPlatforms : [];
    }
    catch {
        // planu.json not present or malformed — not an error
        return [];
    }
}
function platformConfigToDefinition(id, config) {
    return {
        id,
        name: config.name,
        rulesFile: config.rulesFile,
        skillsDir: config.skillsDir,
        format: config.format,
        configFiles: config.configFiles ?? (config.rulesFile ? [config.rulesFile] : []),
    };
}
// === Public API ===
/**
 * Load all platform definitions.
 *
 * 1. Always loads built-in platforms from src/config/agent-platforms.json.
 * 2. If projectPath is provided, also reads planu.json for customPlatforms.
 * 3. Custom platforms take precedence over built-in ones (matched by id).
 */
export async function loadPlatforms(projectPath) {
    const builtIn = await loadBuiltInPlatforms();
    const definitions = new Map(Object.entries(builtIn.platforms).map(([id, config]) => [
        id,
        platformConfigToDefinition(id, config),
    ]));
    if (projectPath) {
        const customs = await loadCustomPlatforms(projectPath);
        for (const custom of customs) {
            // Custom overrides built-in by id
            definitions.set(custom.id, custom);
        }
    }
    return Array.from(definitions.values());
}
/**
 * Find a single platform by id. Returns undefined if not found.
 */
export async function findPlatformById(id, projectPath) {
    const all = await loadPlatforms(projectPath);
    return all.find((p) => p.id === id);
}
//# sourceMappingURL=platform-registry.js.map