// engine/verifier/code-scanner.ts — Spec evidence scanner (SPEC-406)
import { readFile } from 'node:fs/promises';
import { exec } from 'node:child_process';
import { promisify } from 'node:util';
import { glob } from 'glob';
const execAsync = promisify(exec);
const SOURCE_GLOBS = ['**/*.ts', '**/*.js', '**/*.py', '**/*.go', '**/*.java', '**/*.rs'];
const TEST_GLOBS = ['**/*.test.ts', '**/*.spec.ts', '**/*.test.js', '**/*.spec.js'];
const IGNORE_PATTERNS = ['**/node_modules/**', '**/dist/**', '**/.git/**', '**/build/**'];
/**
 * Searches a file for a string reference.
 */
async function fileContains(filePath, term) {
    try {
        const content = await readFile(filePath, 'utf-8');
        return content.includes(term);
    }
    catch {
        return false;
    }
}
/**
 * Retrieves git commit messages that reference the spec ID.
 */
async function findGitCommits(specId, projectPath) {
    try {
        const { stdout } = await execAsync(`git log --oneline --all --grep="${specId}" 2>/dev/null | head -20`, { cwd: projectPath });
        return stdout
            .split('\n')
            .map((l) => l.trim())
            .filter(Boolean);
    }
    catch {
        return [];
    }
}
/**
 * Scans the codebase for evidence that a spec has been implemented.
 * Searches source files, git commits, and test files.
 */
export async function scanForSpecEvidence(specId, projectPath) {
    // Find all source files containing the spec ID
    const allFiles = await glob(SOURCE_GLOBS, {
        cwd: projectPath,
        ignore: IGNORE_PATTERNS,
        absolute: true,
    });
    const filesFoundResults = await Promise.all(allFiles.map(async (f) => {
        const found = await fileContains(f, specId);
        return found ? f : null;
    }));
    const filesFound = filesFoundResults.filter((f) => f !== null);
    // Find git commits mentioning the spec ID
    const gitCommitsFound = await findGitCommits(specId, projectPath);
    // Find test files referencing the spec ID or its slug
    const testFiles = await glob(TEST_GLOBS, {
        cwd: projectPath,
        ignore: IGNORE_PATTERNS,
        absolute: true,
    });
    const testFilesResults = await Promise.all(testFiles.map(async (f) => {
        const found = await fileContains(f, specId);
        return found ? f : null;
    }));
    const testFilesFound = testFilesResults.filter((f) => f !== null);
    return {
        specId,
        filesFound,
        gitCommitsFound,
        testFilesFound,
    };
}
//# sourceMappingURL=code-scanner.js.map