"use strict";
/**
 * Layer 3: AI Semantic Analysis
 * Deep security analysis using Claude AI and package verification
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkPackageAdvisories = exports.checkPackages = exports.batchAnalyzeWithAI = exports.analyzeWithAI = void 0;
exports.runLayer3Scan = runLayer3Scan;
const anthropic_1 = require("./anthropic");
const package_check_1 = require("./package-check");
const osv_check_1 = require("./osv-check");
// File extensions that benefit most from AI analysis
const AI_PRIORITY_EXTENSIONS = [
    '.ts', '.tsx', '.js', '.jsx', '.mjs',
    '.py', '.rb', '.php', '.go',
];
// Max files to send to AI (to control costs)
const MAX_AI_FILES = 10;
// Max file size for AI analysis (smaller than general limit)
const MAX_AI_FILE_SIZE = 30 * 1024; // 30KB
async function runLayer3Scan(files, options = {}) {
    const startTime = Date.now();
    const vulnerabilities = [];
    let aiAnalyzedCount = 0;
    // Use provided maxFiles or default
    const maxAIFiles = options.maxFiles ?? MAX_AI_FILES;
    // Check for cancellation before package check
    if (options.cancellationToken?.cancelled) {
        return {
            vulnerabilities: [],
            filesScanned: files.length,
            duration: Date.now() - startTime,
            aiAnalyzed: 0,
        };
    }
    // 1. Check packages for hallucination/risk (package.json and requirements.txt)
    const packageManifests = files.filter(f => f.path.endsWith('package.json') ||
        f.path.endsWith('requirements.txt'));
    for (const file of packageManifests) {
        // Check for cancellation in package loop
        if (options.cancellationToken?.cancelled)
            break;
        // Run hallucination/risk check (package-check only handles package.json)
        if (file.path.endsWith('package.json')) {
            const packageFindings = await (0, package_check_1.checkPackages)(file.content, file.path);
            vulnerabilities.push(...packageFindings);
        }
        // Run OSV advisory check (handles both npm and Python)
        const osvFindings = await (0, osv_check_1.checkPackageAdvisories)(file.content, file.path);
        vulnerabilities.push(...osvFindings);
    }
    // Check for cancellation before AI analysis
    if (options.cancellationToken?.cancelled) {
        return {
            vulnerabilities,
            filesScanned: files.length,
            duration: Date.now() - startTime,
            aiAnalyzed: 0,
        };
    }
    // 2. AI Analysis (if enabled)
    if (options.enableAI !== false) {
        // Select files for AI analysis
        const aiCandidates = files
            .filter(f => {
            // Must be a priority extension
            const hasPriorityExt = AI_PRIORITY_EXTENSIONS.some(ext => f.path.endsWith(ext));
            // Must be under size limit
            const underSizeLimit = f.size <= MAX_AI_FILE_SIZE;
            // Skip test files
            const isNotTest = !f.path.includes('.test.') &&
                !f.path.includes('.spec.') &&
                !f.path.includes('__tests__');
            return hasPriorityExt && underSizeLimit && isNotTest;
        })
            // Prioritize files that look like they handle user input
            .sort((a, b) => {
            const aScore = getAIPriorityScore(a);
            const bScore = getAIPriorityScore(b);
            return bScore - aScore;
        })
            .slice(0, maxAIFiles);
        if (aiCandidates.length > 0) {
            console.log(`[Layer 3] Analyzing ${aiCandidates.length} files with AI...`);
            try {
                const aiFindings = await (0, anthropic_1.batchAnalyzeWithAI)(aiCandidates, options.projectContext);
                vulnerabilities.push(...aiFindings);
                aiAnalyzedCount = aiCandidates.length;
            }
            catch (error) {
                console.error('[Layer 3] AI analysis failed:', error);
            }
        }
    }
    return {
        vulnerabilities,
        filesScanned: files.length,
        duration: Date.now() - startTime,
        aiAnalyzed: aiAnalyzedCount,
    };
}
// Score files by likelihood of containing security-relevant code
function getAIPriorityScore(file) {
    let score = 0;
    const content = file.content.toLowerCase();
    const path = file.path.toLowerCase();
    // Path-based scoring
    if (path.includes('/api/') || path.includes('/routes/'))
        score += 10;
    if (path.includes('auth') || path.includes('login'))
        score += 8;
    if (path.includes('middleware'))
        score += 7;
    if (path.includes('controller'))
        score += 6;
    if (path.includes('handler'))
        score += 5;
    if (path.includes('service'))
        score += 4;
    // Content-based scoring (indicators of security-relevant code)
    if (content.includes('req.query') || content.includes('req.params'))
        score += 5;
    if (content.includes('req.body'))
        score += 5;
    if (content.includes('searchparams'))
        score += 4;
    if (content.includes('exec(') || content.includes('eval('))
        score += 10;
    if (content.includes('innerhtml') || content.includes('dangerouslysetinnerhtml'))
        score += 8;
    if (content.includes('sql') || content.includes('query('))
        score += 6;
    if (content.includes('password') || content.includes('token'))
        score += 4;
    if (content.includes('authenticate') || content.includes('authorize'))
        score += 5;
    if (content.includes('redirect'))
        score += 3;
    if (content.includes('cookie') || content.includes('session'))
        score += 4;
    return score;
}
var anthropic_2 = require("./anthropic");
Object.defineProperty(exports, "analyzeWithAI", { enumerable: true, get: function () { return anthropic_2.analyzeWithAI; } });
Object.defineProperty(exports, "batchAnalyzeWithAI", { enumerable: true, get: function () { return anthropic_2.batchAnalyzeWithAI; } });
var package_check_2 = require("./package-check");
Object.defineProperty(exports, "checkPackages", { enumerable: true, get: function () { return package_check_2.checkPackages; } });
var osv_check_2 = require("./osv-check");
Object.defineProperty(exports, "checkPackageAdvisories", { enumerable: true, get: function () { return osv_check_2.checkPackageAdvisories; } });
//# sourceMappingURL=index.js.map