// P2: .expect() in production code — HIGH
const EXPECT_PATTERN = /\.expect\s*\("[^"]*"\)/;
// P3: panic! outside tests — HIGH
const PANIC_PATTERN = /\bpanic!\s*\(/;
function isTestFile(filePath) {
    return filePath.includes('_test') || filePath.endsWith('test.rs');
}
function isInTestModule(content, lineIndex) {
    const lines = content.split('\n');
    // Check for #[cfg(test)] or #[test] in surrounding context
    const windowStart = Math.max(0, lineIndex - 20);
    for (let i = windowStart; i <= lineIndex; i++) {
        const line = lines[i] ?? '';
        if (line.includes('#[cfg(test)]') || line.includes('#[test]')) {
            return true;
        }
    }
    return false;
}
function detectP1(filePath, content) {
    const risks = [];
    if (isTestFile(filePath)) {
        return risks;
    }
    const lines = content.split('\n');
    for (let i = 0; i < lines.length; i++) {
        const line = lines[i] ?? '';
        if (line.includes('.unwrap()') && !isInTestModule(content, i)) {
            risks.push({
                file: filePath,
                line: i + 1,
                pattern: 'RUST_UNWRAP_IN_PRODUCTION',
                severity: 'CRITICAL',
                description: '.unwrap() panics on Err/None at runtime. Production code must handle error cases explicitly.',
                suggestedFix: 'Use pattern matching, unwrap_or, unwrap_or_else, or the ? operator to propagate errors.',
                autoFixable: false,
            });
        }
    }
    return risks;
}
function detectP2(filePath, content) {
    const risks = [];
    if (isTestFile(filePath)) {
        return risks;
    }
    const lines = content.split('\n');
    for (let i = 0; i < lines.length; i++) {
        const line = lines[i] ?? '';
        if (EXPECT_PATTERN.test(line) && !isInTestModule(content, i)) {
            risks.push({
                file: filePath,
                line: i + 1,
                pattern: 'RUST_EXPECT_IN_PRODUCTION',
                severity: 'HIGH',
                description: '.expect() panics with a message on Err/None. Better than .unwrap() but still crashes in production.',
                suggestedFix: 'Use proper error handling with ? operator or match. Reserve .expect() for tests and initialization.',
                autoFixable: false,
            });
        }
    }
    return risks;
}
function detectP3(filePath, content) {
    const risks = [];
    if (isTestFile(filePath)) {
        return risks;
    }
    const lines = content.split('\n');
    for (let i = 0; i < lines.length; i++) {
        const line = lines[i] ?? '';
        if (PANIC_PATTERN.test(line) && !isInTestModule(content, i)) {
            risks.push({
                file: filePath,
                line: i + 1,
                pattern: 'RUST_PANIC_IN_PRODUCTION',
                severity: 'HIGH',
                description: 'panic!() terminates the thread/process in production. Should only be used in tests or truly unrecoverable states.',
                suggestedFix: 'Return a Result<T, E> instead of panicking. Use panic! only in test code or for truly impossible states.',
                autoFixable: false,
            });
        }
    }
    return risks;
}
export const rustDetector = {
    language: 'Rust',
    fileExtensions: ['.rs'],
    detect(filePath, content) {
        return [
            ...detectP1(filePath, content),
            ...detectP2(filePath, content),
            ...detectP3(filePath, content),
        ];
    },
};
//# sourceMappingURL=rust-detector.js.map