import { extractAcLines, computeCoverageScore, containsAny } from './pattern-matcher.js';
import { selectRules } from './gap-rules.js';
import { PRIORITY_ORDER, WEB_UI_KEYWORDS } from './constants.js';
/** Minimum priority filter: only include suggestions at or above this level. */
const DEFAULT_MIN_PRIORITY = 'medium';
/**
 * Analyzes the provided spec text for missing acceptance criteria.
 *
 * @param specId         - Spec identifier (for the report).
 * @param specText       - Raw text of spec.md (may include frontmatter).
 * @param technicalText  - Raw text of technical.md (optional, pass empty string if unavailable).
 * @param categories     - Optional list of categories to focus on (default: all).
 * @param minPriority    - Minimum priority to include in results (default: medium).
 * @returns AcGapReport with suggested missing ACs.
 */
export function analyzeAcGaps(specId, specText, technicalText, categories, minPriority = DEFAULT_MIN_PRIORITY) {
    const combined = `${specText}\n${technicalText}`;
    const fullText = combined.toLowerCase();
    const acLines = extractAcLines(combined);
    const hasWebUi = containsAny(fullText, WEB_UI_KEYWORDS);
    const idCounter = { value: 0 };
    const ctx = { fullText, acLines, hasWebUi, idCounter };
    const rules = selectRules(categories);
    const allGaps = rules
        .map((rule) => rule(ctx))
        .filter((g) => g !== null);
    const minWeight = PRIORITY_ORDER[minPriority];
    const filtered = allGaps.filter((g) => PRIORITY_ORDER[g.priority] >= minWeight);
    // Sort by priority descending
    filtered.sort((a, b) => PRIORITY_ORDER[b.priority] - PRIORITY_ORDER[a.priority]);
    // Coverage score: ratio of rule categories that produced no gap
    const gappedCategories = new Set(filtered.map((g) => g.category));
    const coveredCount = rules.length - gappedCategories.size;
    const coverageScore = computeCoverageScore(new Set(Array.from({ length: Math.max(0, coveredCount) }, (_, i) => String(i))), rules.length);
    return {
        specId,
        existingAcCount: acLines.length,
        gaps: filtered,
        coverageScore,
        analyzedAt: new Date().toISOString(),
    };
}
//# sourceMappingURL=analyze-gaps.js.map