/**
 * Unified config directory discovery and management.
 *
 * Collects built-in + custom directories scanned for skills, MCP servers, and tools.
 * Custom directories are stored in `config_directories` in project.yaml,
 * with backward compatibility for the legacy `skill_directories` key.
 */
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { profile, bumpCount } from "./profiling.js";
/** Expand ~ to home directory and resolve the path. */
function expandPath(p) {
    if (p.startsWith("~")) {
        return path.resolve(path.join(os.homedir(), p.slice(1)));
    }
    return path.resolve(p);
}
/**
 * Parse custom directories from project config, merging both
 * `config_directories` and legacy `skill_directories` keys.
 *
 * Deduplicates by normalized path. If the same path exists in both,
 * `config_directories` wins (it may have broader types).
 */
export function parseCustomDirectories(projectConfigStore) {
    const byPath = new Map();
    // 1. Parse skill_directories (legacy) — types: ["skills"]
    const skillDirsRaw = projectConfigStore.get("skill_directories");
    if (skillDirsRaw) {
        try {
            const parsed = JSON.parse(skillDirsRaw);
            if (Array.isArray(parsed)) {
                for (const entry of parsed) {
                    if (typeof entry === "object" && entry !== null &&
                        typeof entry.path === "string" && entry.path.trim().length > 0) {
                        const resolved = expandPath(entry.path);
                        byPath.set(resolved, { path: resolved, types: ["skills"] });
                    }
                }
            }
        }
        catch (err) {
            console.warn("[config-directories] Invalid skill_directories JSON, ignoring:", err);
        }
    }
    // 2. Parse config_directories (new unified key) — overwrites on conflict.
    //    Prefer the native typed accessor; fall back to the legacy JSON-string for
    //    test mocks that don't implement it.
    let entries = null;
    if (typeof projectConfigStore.getConfigDirectories === "function") {
        try {
            entries = projectConfigStore.getConfigDirectories();
        }
        catch {
            entries = null;
        }
    }
    if (!entries) {
        const configDirsRaw = projectConfigStore.get("config_directories");
        if (configDirsRaw) {
            try {
                const parsed = JSON.parse(configDirsRaw);
                if (Array.isArray(parsed))
                    entries = parsed;
            }
            catch (err) {
                console.warn("[config-directories] Invalid config_directories JSON, ignoring:", err);
            }
        }
    }
    if (entries) {
        for (const entry of entries) {
            if (typeof entry === "object" && entry !== null &&
                typeof entry.path === "string" && entry.path.trim().length > 0 &&
                Array.isArray(entry.types) && entry.types.length > 0) {
                const resolved = expandPath(entry.path);
                const types = entry.types.filter((t) => t === "skills" || t === "mcp" || t === "tools" || t === "agents");
                if (types.length > 0) {
                    byPath.set(resolved, { path: resolved, types });
                }
            }
        }
    }
    return Array.from(byPath.values());
}
/**
 * Get all config directories (built-in + custom) with existence checks.
 */
function existsSyncCounted(p) {
    bumpCount("getAllConfigDirectories.existsSync");
    return fs.existsSync(p);
}
export function getAllConfigDirectories(cwd, projectConfigStore) {
    return profile("getAllConfigDirectories", () => _getAllConfigDirectories(cwd, projectConfigStore));
}
function _getAllConfigDirectories(cwd, projectConfigStore) {
    const dirs = [];
    // ── Skills (5 built-in) ──
    const skillDirs = [
        { p: path.join(cwd, ".claude", "skills"), scope: "project" },
        { p: path.join(cwd, ".bobbit", "skills"), scope: "project" },
        { p: path.join(os.homedir(), ".claude", "skills"), scope: "user" },
        { p: path.join(os.homedir(), ".bobbit", "skills"), scope: "user" },
        { p: path.join(cwd, ".claude", "commands"), scope: "project" },
    ];
    for (const { p, scope } of skillDirs) {
        const resolved = path.resolve(p);
        dirs.push({
            path: resolved,
            types: ["skills"],
            scope,
            exists: existsSyncCounted(resolved),
            isRemovable: false,
        });
    }
    // ── MCP (6 built-in) ──
    const mcpDirs = [
        { p: path.join(os.homedir(), ".claude.json"), scope: "user" },
        { p: path.join(os.homedir(), ".claude", ".mcp.json"), scope: "user" },
        { p: path.join(os.homedir(), ".bobbit", ".mcp.json"), scope: "user" },
        { p: path.join(cwd, ".mcp.json"), scope: "project" },
        { p: path.join(cwd, ".claude", ".mcp.json"), scope: "project" },
        { p: path.join(cwd, ".bobbit", "config", "mcp.json"), scope: "project" },
    ];
    for (const { p, scope } of mcpDirs) {
        const resolved = path.resolve(p);
        dirs.push({
            path: resolved,
            types: ["mcp"],
            scope,
            exists: existsSyncCounted(resolved),
            isRemovable: false,
        });
    }
    // ── Tools (1 built-in) ──
    const toolsDir = path.resolve(path.join(cwd, ".bobbit", "config", "tools"));
    dirs.push({
        path: toolsDir,
        types: ["tools"],
        scope: "project",
        exists: existsSyncCounted(toolsDir),
        isRemovable: false,
    });
    // ── Agents (1 built-in — file path, not directory) ──
    const agentsMdPath = path.resolve(path.join(cwd, "AGENTS.md"));
    const claudeMdPath = path.resolve(path.join(cwd, "CLAUDE.md"));
    const agentsMdExists = existsSyncCounted(agentsMdPath);
    const claudeMdExists = !agentsMdExists && existsSyncCounted(claudeMdPath);
    const builtinAgentPath = agentsMdExists ? agentsMdPath : claudeMdExists ? claudeMdPath : agentsMdPath;
    dirs.push({
        path: builtinAgentPath,
        types: ["agents"],
        scope: "project",
        exists: agentsMdExists || claudeMdExists,
        isRemovable: false,
    });
    // ── Custom directories ──
    const customDirs = parseCustomDirectories(projectConfigStore);
    for (const entry of customDirs) {
        dirs.push({
            path: entry.path,
            types: entry.types,
            scope: "custom",
            exists: existsSyncCounted(entry.path),
            isRemovable: true,
        });
    }
    return dirs;
}
/**
 * Remove a built-in directory from scanning by adding it to the
 * `disabled_config_directories` list in project config.
 */
export function removeBuiltinDirectory(projectConfigStore, dirPath) {
    const resolved = expandPath(dirPath);
    const raw = projectConfigStore.get("disabled_config_directories");
    let disabled = [];
    if (raw) {
        try {
            disabled = JSON.parse(raw);
        }
        catch {
            disabled = [];
        }
    }
    if (!disabled.includes(resolved)) {
        disabled.push(resolved);
    }
    projectConfigStore.set("disabled_config_directories", JSON.stringify(disabled));
}
/**
 * Reset config directories to defaults by clearing both custom and disabled lists.
 */
export function resetConfigDirectories(projectConfigStore) {
    projectConfigStore.remove("config_directories");
    projectConfigStore.remove("skill_directories");
    projectConfigStore.remove("disabled_config_directories");
}
/**
 * Save custom directories to project config via the `config_directories` key.
 * Also removes the legacy `skill_directories` key to prevent stale entries
 * from reappearing on next read (migrate forward).
 */
export function saveCustomDirectories(projectConfigStore, dirs) {
    const serializable = dirs.map((d) => ({
        path: d.path,
        types: d.types,
    }));
    if (typeof projectConfigStore.setConfigDirectories === "function") {
        projectConfigStore.setConfigDirectories(serializable);
    }
    else {
        projectConfigStore.set("config_directories", JSON.stringify(serializable));
    }
    projectConfigStore.remove("skill_directories");
}
//# sourceMappingURL=config-directories.js.map