import { messages } from '../../../core/messages/index.js';
import { createLineLookup, maskRustComments } from '../../../shared/helpers/index.js';
import { criarAnalista, criarOcorrencia } from '../../../types/index.js';
const disableEnv = process.env.TUTANUS_DISABLE_PLUGIN_RUST === '1';
function warn(message, relPath, line, nivel) {
    return criarOcorrencia({
        relPath,
        mensagem: message,
        linha: line,
        nivel: nivel ?? messages.SeverityNiveis.warning,
        origem: messages.AnalystOrigens.rust,
        tipo: messages.AnalystTipos.rust
    });
}
function collectMemoryIssues(src, relPath) {
    const ocorrencias = [];
    const lineOf = createLineLookup(src).lineAt;
    const scan = maskRustComments(src);
    for (const match of scan.matchAll(/(\w+)\.push\(/g)) {
        const line = lineOf(match.index);
        const varName = match[1] ?? '';
        const declMatch = new RegExp(`let\\s+mut\\s+${varName}\\s*:\\s*Vec|<|=\\s*Vec::new\\(\\)`, 'i');
        if (declMatch.test(scan.slice(0, match.index))) {
            ocorrencias.push(warn(messages.RustMensagens.vecWithoutCapacity, relPath, line, messages.SeverityNiveis.suggestion));
        }
    }
    for (const match of scan.matchAll(/(\w+)\.read_line\(&mut\s+(\w+)\)/g)) {
        const line = lineOf(match.index);
        const varName = match[2] ?? '';
        const snippet = src.slice(match.index, match.index + 200);
        if (!snippet.includes(`${varName}.trim()`) && !snippet.includes(`${varName}.trim_end()`)) {
            ocorrencias.push(warn(messages.RustMensagens.noTrimOnInput, relPath, line));
        }
    }
    for (const match of scan.matchAll(/\bBox::new\s*\(([^)]{0,20})\)/g)) {
        const line = lineOf(match.index);
        const inner = match[1];
        if (inner && (inner.includes('[') || inner.includes('{'))) {
            ocorrencias.push(warn('Box::new with inline allocation; consider using Box::new only for heap allocation', relPath, line, messages.SeverityNiveis.info));
        }
    }
    for (const match of scan.matchAll(/for\s+\w+\s+in\s+[\s\S]{0,200}\{[\s\S]{0,500}\w+\s*\+=\s*["'`]/gi)) {
        const line = lineOf(match.index);
        ocorrencias.push(warn('String concatenation in loop; use String::with_capacity and push_str', relPath, line, messages.SeverityNiveis.suggestion));
    }
    return ocorrencias;
}
export const analistaRustMemoria = criarAnalista({
    nome: 'analista-rust-memoria',
    categoria: 'memoria',
    descricao: 'Detecta problemas de alocação e gerenciamento de memória em código Rust.',
    global: false,
    test: (relPath) => /\.(rs)$/i.test(relPath),
    aplicar: async (src, relPath) => {
        if (disableEnv)
            return null;
        const msgs = collectMemoryIssues(src, relPath);
        return msgs.length ? msgs : null;
    }
});
//# sourceMappingURL=analyst-memory.js.map