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 collectConcurrencyIssues(src, relPath) {
    const ocorrencias = [];
    const lineOf = createLineLookup(src).lineAt;
    const scan = maskRustComments(src);
    for (const match of scan.matchAll(/(\w+)\.lock\(\)\.unwrap\(\)/g)) {
        const line = lineOf(match.index);
        const afterLock = src.slice(match.index, match.index + 300);
        if (/\.await\b/.test(afterLock)) {
            ocorrencias.push(warn(messages.RustMensagens.mutexAcrossAwait, relPath, line, messages.SeverityNiveis.error));
        }
    }
    for (const match of scan.matchAll(/(\w+)\.(?:read|write)\(\)\.unwrap\(\)/g)) {
        const line = lineOf(match.index);
        const afterLock = src.slice(match.index, match.index + 300);
        if (/\.await\b/.test(afterLock)) {
            ocorrencias.push(warn('RwLock guard held across .await; potential deadlock', relPath, line, messages.SeverityNiveis.error));
        }
    }
    for (const match of scan.matchAll(/\bArc\s*::\s*new\s*\(/g)) {
        const line = lineOf(match.index);
        const snippet = src.slice(match.index, match.index + 200);
        if (snippet.includes('Mutex') || snippet.includes('RwLock') || snippet.includes('Atomic'))
            continue;
        if (snippet.match(/Arc::new\([^)]*\)/) && !snippet.includes('Mutex') && !snippet.includes('RwLock')) {
            ocorrencias.push(warn('Arc::new() wrapping non-atomic type; consider Mutex or RwLock for interior mutability', relPath, line, messages.SeverityNiveis.suggestion));
        }
    }
    for (const match of scan.matchAll(/\bthread::spawn\s*\(/g)) {
        const line = lineOf(match.index);
        const srcBefore = src.slice(0, match.index);
        const srcAfter = src.slice(match.index, match.index + 200);
        if (!srcBefore.includes('JoinHandle') && !srcBefore.includes('let') && !srcAfter.includes('join()')) {
            ocorrencias.push(warn('thread::spawn without JoinHandle; consider storing handle to join later', relPath, line, messages.SeverityNiveis.info));
        }
    }
    return ocorrencias;
}
export const analistaRustConcorrencia = criarAnalista({
    nome: 'analista-rust-concorrencia',
    categoria: 'concorrencia',
    descricao: 'Detecta problemas de concorrência em código Rust.',
    global: false,
    test: (relPath) => /\.(rs)$/i.test(relPath),
    aplicar: async (src, relPath) => {
        if (disableEnv)
            return null;
        const msgs = collectConcurrencyIssues(src, relPath);
        return msgs.length ? msgs : null;
    }
});
//# sourceMappingURL=analyst-concurrency.js.map