// @crash-shield-ignore-file — config/cache reader for Planu-controlled JSON; writer is this codebase, shape guaranteed by build/seed.
// engine/event-detector.ts — Detects event brokers from project dependencies (SPEC-031)
// Reads event-brokers.json config and matches against project stack/dependencies.
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = fileURLToPath(new URL('.', import.meta.url));
/**
 * Load broker configuration from the JSON config file.
 * Cached after first read.
 */
let _cachedConfig = null;
function loadBrokerConfig() {
    if (_cachedConfig !== null) {
        return _cachedConfig;
    }
    const configPath = join(__dirname, '..', 'config', 'event-brokers.json');
    try {
        const raw = readFileSync(configPath, 'utf-8');
        _cachedConfig = JSON.parse(raw);
    }
    catch {
        // Fallback to empty config when file is missing or malformed
        _cachedConfig = { brokers: [] };
    }
    return _cachedConfig;
}
/**
 * Detect which message broker(s) the project uses by scanning the provided
 * dependency identifiers (package names, framework names, stack tags).
 *
 * Returns all matched brokers in detection order. If nothing matched, returns
 * a single-element array with `'unknown'`.
 */
export function detectBrokers(dependencies) {
    if (!dependencies || dependencies.length === 0) {
        return ['unknown'];
    }
    const config = loadBrokerConfig();
    const detected = [];
    for (const broker of config.brokers) {
        const matched = broker.detectionPatterns.some((pattern) => dependencies.some((dep) => dep.toLowerCase().includes(pattern.toLowerCase())));
        if (matched) {
            detected.push(broker.id);
        }
    }
    return detected.length > 0 ? detected : ['unknown'];
}
/**
 * Return the full BrokerConfig for a given broker ID, or null if not found.
 */
export function getBrokerConfig(brokerId) {
    const config = loadBrokerConfig();
    return config.brokers.find((b) => b.id === brokerId) ?? null;
}
/**
 * Return true when the given broker guarantees at-least-once delivery
 * (which means consumers MUST be idempotent).
 */
export function requiresIdempotence(brokerId) {
    const broker = getBrokerConfig(brokerId);
    if (!broker) {
        return false;
    }
    /* v8 ignore next 2 */ // 'exactly-once' branch: no broker in current config uses this value
    return (broker.deliveryGuarantee === 'at-least-once' || broker.deliveryGuarantee === 'exactly-once');
}
/**
 * Return true when the given broker supports dead-letter queues natively
 * or via a common pattern (retry topic, DLX, etc.).
 */
export function supportsDLQ(brokerId) {
    const broker = getBrokerConfig(brokerId);
    if (!broker) {
        return false;
    }
    /* v8 ignore next 1 */ // empty-string dlqSupport: no broker in current config has this value
    return broker.dlqSupport !== 'none' && broker.dlqSupport !== '';
}
/**
 * Given a list of project stack/dependency identifiers, determine if the project
 * is event-driven and return the primary broker (first detected).
 */
export function detectPrimaryBroker(stack) {
    const brokers = detectBrokers(stack);
    // detectBrokers always returns a non-empty array; ?? 'unknown' fallback is unreachable
    /* v8 ignore start */
    return brokers[0] ?? 'unknown';
    /* v8 ignore stop */
}
/**
 * Reset the cached config (used in tests to ensure fresh reads).
 */
export function resetBrokerConfigCache() {
    _cachedConfig = null;
}
//# sourceMappingURL=event-detector.js.map