// engine/plugins/extensions/analyzer-extension.ts — Analyzer registration (SPEC-085 AC-06)
import { withPluginTimeout } from '../sandbox.js';
/** Registry of plugin analyzers keyed by `{pluginId}:{analyzerName}` */
const analyzerRegistry = new Map();
function analyzerKey(pluginId, analyzerName) {
    return `${pluginId}:${analyzerName}`;
}
/**
 * Registers analyzers from a plugin.
 */
export function registerPluginAnalyzers(pluginId, analyzers) {
    const registered = [];
    for (const analyzer of analyzers) {
        const key = analyzerKey(pluginId, analyzer.name);
        if (analyzerRegistry.has(key)) {
            throw new Error(`Analyzer "${analyzer.name}" already registered for plugin "${pluginId}"`);
        }
        analyzerRegistry.set(key, { pluginId, definition: analyzer });
        registered.push(key);
    }
    return registered;
}
/**
 * Unregisters all analyzers belonging to a plugin.
 */
export function unregisterPluginAnalyzers(pluginId) {
    const removed = [];
    for (const [key, entry] of analyzerRegistry) {
        if (entry.pluginId === pluginId) {
            analyzerRegistry.delete(key);
            removed.push(key);
        }
    }
    return removed;
}
/**
 * Simple glob matching: supports * and ** wildcards.
 * `**` matches any number of path segments (including zero).
 * `*` matches anything except `/`.
 */
function matchGlob(pattern, filePath) {
    const regexStr = pattern
        .replace(/[.+^${}()|[\]\\]/g, '\\$&')
        .replace(/\*\*\//g, '(?:.*/)?')
        .replace(/\*\*/g, '.*')
        .replace(/\*/g, '[^/]*');
    const regex = new RegExp(`^${regexStr}$`);
    return regex.test(filePath);
}
/**
 * Runs all registered plugin analyzers against the given files.
 * Results are tagged with [plugin:{pluginId}].
 */
export async function runPluginAnalyzers(files) {
    const output = [];
    for (const [, entry] of analyzerRegistry) {
        const matchingFiles = files.filter((f) => entry.definition.filePatterns.some((pattern) => matchGlob(pattern, f)));
        if (matchingFiles.length === 0) {
            continue;
        }
        try {
            const results = await withPluginTimeout(entry.pluginId, `analyzer:${entry.definition.name}`, () => entry.definition.analyze([...matchingFiles]));
            output.push({ pluginId: entry.pluginId, results });
        }
        catch (err) {
            const msg = err instanceof Error ? err.message : String(err);
            output.push({
                pluginId: entry.pluginId,
                results: [
                    {
                        file: '',
                        severity: 'error',
                        message: `Analyzer error: ${msg}`,
                        rule: `plugin:${entry.pluginId}:${entry.definition.name}`,
                    },
                ],
            });
        }
    }
    return output;
}
/**
 * Returns the count of analyzers registered for a specific plugin.
 */
export function getPluginAnalyzerCount(pluginId) {
    let count = 0;
    for (const entry of analyzerRegistry.values()) {
        if (entry.pluginId === pluginId) {
            count++;
        }
    }
    return count;
}
/**
 * Clears all analyzer registrations (for testing).
 */
export function clearAnalyzerRegistry() {
    analyzerRegistry.clear();
}
//# sourceMappingURL=analyzer-extension.js.map