/*
 * Copyright 2026, Jaime Terrats.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { existsSync, readdirSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
export const REGISTRY_DIR = '.setup-agents/rules';
/**
 * Loads all neutral rules from the registry directory.
 * Each rule is a JSON file in `.setup-agents/rules/` with the NeutralRule shape.
 */
export function loadRegistry(cwd) {
    const dir = join(cwd, REGISTRY_DIR);
    if (!existsSync(dir))
        return [];
    const files = readdirSync(dir).filter((f) => f.endsWith('.json'));
    const rules = [];
    for (const file of files) {
        try {
            const raw = readFileSync(join(dir, file), 'utf-8');
            const parsed = JSON.parse(raw);
            if (isNeutralRule(parsed)) {
                rules.push(parsed);
            }
        }
        catch {
            // Skip malformed files silently
        }
    }
    return rules;
}
/** Returns all rules that apply to a given profile ID. */
export function getRulesForProfile(rules, profileId) {
    return rules.filter((rule) => rule.appliesTo.includes(profileId) || rule.appliesTo.includes('*'));
}
/** Renders a neutral rule into the target runtime's format. */
export function renderForTarget(rule, target) {
    switch (target) {
        case 'cursor':
            return renderCursorMdc(rule);
        case 'claude':
            return renderClaudeMd(rule);
        case 'codex':
            return renderCodexMd(rule);
        case 'vscode':
            return renderVsCodeMd(rule);
        case 'windsurf':
            return renderWindsurfMd(rule);
    }
}
/** Returns the file path where a rule should be written for the given target. */
export function getTargetPath(cwd, rule, target) {
    switch (target) {
        case 'cursor':
            return join(cwd, '.cursor', 'rules', `${rule.id}.mdc`);
        case 'claude':
            return join(cwd, '.claude', 'rules', `${rule.id}.md`);
        case 'codex':
            return join(cwd, '.codex', `${rule.id}.md`);
        case 'vscode':
            return join(cwd, '.github', 'copilot-instructions', `${rule.id}.md`);
        case 'windsurf':
            return join(cwd, '.windsurf', 'rules', `${rule.id}.md`);
    }
}
// ─── Internal renderers ──────────────────────────────────────────────────────
function renderCursorMdc(rule) {
    const frontmatter = ['---', `description: ${rule.title}`, 'globs:', 'alwaysApply: true', '---'].join('\n');
    return `${frontmatter}\n\n# ${rule.title}\n\n${rule.content}\n`;
}
function renderClaudeMd(rule) {
    return `# ${rule.title}\n\n${rule.content}\n`;
}
function renderCodexMd(rule) {
    return `# ${rule.title}\n\n${rule.content}\n`;
}
function renderVsCodeMd(rule) {
    return `# ${rule.title}\n\n${rule.content}\n`;
}
function renderWindsurfMd(rule) {
    return `# ${rule.title}\n\n${rule.content}\n`;
}
// ─── Validation ──────────────────────────────────────────────────────────────
function isNeutralRule(value) {
    if (typeof value !== 'object' || value === null)
        return false;
    const obj = value;
    return (typeof obj.id === 'string' &&
        typeof obj.title === 'string' &&
        typeof obj.content === 'string' &&
        Array.isArray(obj.tags) &&
        obj.tags.every((t) => typeof t === 'string') &&
        Array.isArray(obj.appliesTo) &&
        obj.appliesTo.every((a) => typeof a === 'string'));
}
//# sourceMappingURL=rule-registry.js.map