// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
/**
 * SPEC-686 Scenario 4: Filter out candidates that share files with implementing specs.
 *
 * A conflict exists when candidate.technicalFiles ∩ activeSpec.technicalFiles is non-empty.
 * technicalFiles extracted from spec.technical?.filesToModify + spec.technical?.filesToCreate.
 *
 * Specs with no file info (draft/rough specs) are treated as conflict-free and included.
 *
 * @param candidates - specs to evaluate (approved, not blocked by deps)
 * @param activeSpecs - all specs currently with status === 'implementing'
 */
export function filterConflicting(candidates, activeSpecs) {
    if (activeSpecs.length === 0) {
        return candidates;
    }
    const activeFiles = buildFileSet(activeSpecs);
    if (activeFiles.size === 0) {
        return candidates;
    }
    return candidates.filter((spec) => {
        const specFiles = extractFiles(spec);
        // No file info → no conflict (treat as safe)
        if (specFiles.length === 0) {
            return true;
        }
        return !specFiles.some((f) => activeFiles.has(f));
    });
}
/**
 * Build a set of all files owned by the active (implementing) specs.
 */
function buildFileSet(specs) {
    const files = new Set();
    for (const spec of specs) {
        for (const f of extractFiles(spec)) {
            files.add(f);
        }
    }
    return files;
}
/**
 * Extract all file paths from a spec's technical section.
 * Reads filesToModify and filesToCreate from spec.technical.
 */
export function extractFiles(spec) {
    const technical = spec.technical;
    if (!technical) {
        return [];
    }
    const files = [];
    const filesToModify = technical.filesToModify;
    if (Array.isArray(filesToModify)) {
        for (const f of filesToModify) {
            if (typeof f === 'string' && f.trim()) {
                files.push(f.trim());
            }
        }
    }
    const filesToCreate = technical.filesToCreate;
    if (Array.isArray(filesToCreate)) {
        for (const f of filesToCreate) {
            if (typeof f === 'string' && f.trim()) {
                files.push(f.trim());
            }
        }
    }
    return files;
}
/**
 * Check if two specs share any files (used by orchestration planner).
 */
export function hasFileConflict(specA, specB) {
    const filesA = extractFiles(specA);
    const filesB = new Set(extractFiles(specB));
    return filesA.some((f) => filesB.has(f));
}
//# sourceMappingURL=conflict-filter.js.map