// tools/validate-annotations.ts — Validate @spec annotations in source code
// Checks that all annotated spec IDs exist and criteria numbers are valid.
import { specStore } from '../storage/index.js';
import { parseAnnotationsFromProject } from '../engine/living-spec/index.js';
import { extractCriteria } from '../engine/validator/extractors.js';
export async function handleValidateAnnotations(args) {
    const { projectId, projectPath, specId: filterSpecId } = args;
    // 1. Parse annotations from project
    const parseResult = await parseAnnotationsFromProject(projectPath, filterSpecId);
    if (parseResult.annotations.length === 0) {
        return {
            content: [
                {
                    type: 'text',
                    text: JSON.stringify({
                        message: 'No @spec annotations found in project',
                        fileCount: parseResult.fileCount,
                        annotatedFileCount: 0,
                    }, null, 2),
                },
            ],
        };
    }
    // 2. Validate each annotation against stored specs
    const valid = [];
    const invalid = [];
    // Cache specs to avoid repeated lookups
    const specCache = new Map();
    const criteriaCache = new Map();
    for (const annotation of parseResult.annotations) {
        // Check if spec exists
        let spec = specCache.get(annotation.specId);
        if (spec === undefined) {
            spec = await specStore.getSpec(projectId, annotation.specId);
            specCache.set(annotation.specId, spec);
        }
        if (!spec) {
            invalid.push({
                annotation,
                reason: `Spec ${annotation.specId} not found in project`,
            });
            continue;
        }
        // Check criteria numbers if specified
        if (annotation.criteria.length > 0) {
            let criteriaList = criteriaCache.get(annotation.specId);
            if (criteriaList === undefined) {
                criteriaList = await extractCriteria(spec);
                criteriaCache.set(annotation.specId, criteriaList);
            }
            const maxCriterion = criteriaList.length;
            const invalidCriteria = annotation.criteria.filter((c) => c > maxCriterion || c < 1);
            if (invalidCriteria.length > 0) {
                invalid.push({
                    annotation,
                    reason: `Invalid criteria AC-${invalidCriteria.join(', AC-')}: spec has ${maxCriterion} criteria`,
                });
                continue;
            }
        }
        valid.push({
            annotation,
            reason: 'Valid annotation',
        });
    }
    const result = {
        valid,
        invalid,
        totalAnnotations: parseResult.annotations.length,
        validCount: valid.length,
        invalidCount: invalid.length,
    };
    return {
        content: [
            {
                type: 'text',
                text: JSON.stringify({
                    ...result,
                    fileCount: parseResult.fileCount,
                    annotatedFileCount: parseResult.annotatedFileCount,
                    message: invalid.length > 0
                        ? `${invalid.length} invalid annotation(s) found. Review and fix before proceeding.`
                        : `All ${valid.length} annotation(s) are valid.`,
                }, null, 2),
            },
        ],
        isError: invalid.length > 0 ? true : undefined,
    };
}
//# sourceMappingURL=validate-annotations.js.map