// engine/crash-shield/file-collector.ts — File discovery for crash shield (SPEC-442)
import { glob } from 'glob';
import { join } from 'node:path';
const STACK_EXTENSIONS = {
    TypeScript: ['.ts', '.tsx'],
    JavaScript: ['.js', '.jsx', '.mjs', '.cjs'],
    Python: ['.py'],
    Go: ['.go'],
    Rust: ['.rs'],
    Java: ['.java'],
    PHP: ['.php'],
    Ruby: ['.rb'],
};
const MAX_FILES = 400;
const IGNORE_PATTERNS = [
    '**/node_modules/**',
    '**/dist/**',
    '**/.git/**',
    '**/*.d.ts',
    '**/*.min.js',
];
/**
 * Collects files from the project path, detects the stack, and returns up to MAX_FILES paths.
 * Optionally filters by enabled languages.
 */
export async function collectFiles(projectPath, enabledLanguages) {
    const extensions = buildExtensionList(enabledLanguages);
    const pattern = buildGlobPattern(extensions);
    const allFiles = await glob(pattern, {
        cwd: projectPath,
        ignore: IGNORE_PATTERNS,
        absolute: true,
        nodir: true,
    });
    const files = allFiles.slice(0, MAX_FILES).map((f) => join(f));
    const detectedStack = detectStack(files);
    return { files, detectedStack };
}
function buildExtensionList(enabledLanguages) {
    if (!enabledLanguages || enabledLanguages.length === 0) {
        return Object.values(STACK_EXTENSIONS).flat();
    }
    return enabledLanguages.flatMap((lang) => STACK_EXTENSIONS[lang] ?? []);
}
function buildGlobPattern(extensions) {
    if (extensions.length === 0) {
        return '**/*';
    }
    if (extensions.length === 1) {
        return `**/*${extensions[0]}`;
    }
    const joined = extensions.join(',');
    return `**/*{${joined}}`;
}
function detectStack(files) {
    const detected = new Set();
    for (const file of files) {
        for (const [lang, exts] of Object.entries(STACK_EXTENSIONS)) {
            if (exts.some((ext) => file.endsWith(ext))) {
                detected.add(lang);
            }
        }
    }
    return [...detected].sort();
}
/**
 * Processes items in sequential batches to avoid unbounded concurrency.
 * Each batch runs in parallel internally, but batches are processed one at a time.
 * Prevents spawning thousands of concurrent operations (e.g. 1000 files × N detectors).
 */
export async function processBatched(items, batchSize, fn) {
    const results = [];
    for (let i = 0; i < items.length; i += batchSize) {
        const batch = items.slice(i, i + batchSize);
        const batchResults = await Promise.all(batch.map(fn));
        results.push(...batchResults);
    }
    return results;
}
//# sourceMappingURL=file-collector.js.map