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 collectSecurityIssues(src, relPath) {
    const ocorrencias = [];
    const lineOf = createLineLookup(src).lineAt;
    const scan = maskRustComments(src);
    for (const match of scan.matchAll(/\.unwrap\(\)/g)) {
        const line = lineOf(match.index);
        ocorrencias.push(warn(messages.RustMensagens.unwrapUsage, relPath, line, messages.SeverityNiveis.error));
    }
    for (const match of scan.matchAll(/\.expect\(\)/g)) {
        const line = lineOf(match.index);
        ocorrencias.push(warn(messages.RustMensagens.emptyExpect, relPath, line));
    }
    for (const match of scan.matchAll(/\bunsafe\s*\{/g)) {
        const line = lineOf(match.index);
        ocorrencias.push(warn(messages.RustMensagens.unsafeBlock, relPath, line, messages.SeverityNiveis.error));
    }
    for (const match of scan.matchAll(/\b(?:std::)?mem::transmute\b/g)) {
        const line = lineOf(match.index);
        ocorrencias.push(warn(messages.RustMensagens.transmuteUsage, relPath, line, messages.SeverityNiveis.error));
    }
    for (const match of scan.matchAll(/(?:password|secret|api[_-]?key|token|credential|senha)\s*(?::\s*|=\s*["'`])([^"'`\s]{4,})/gi)) {
        const line = lineOf(match.index);
        const value = match[1];
        if (value.includes('env!') || value.includes('env::var'))
            continue;
        ocorrencias.push(warn(messages.RustMensagens.hardcodedSecret, relPath, line, messages.SeverityNiveis.error));
    }
    for (const match of scan.matchAll(/\bunsafe\s+(?:trait|impl|fn)\b/g)) {
        const line = lineOf(match.index);
        ocorrencias.push(warn(`Unsafe ${match[1]} declaration; document safety invariants with // SAFETY:`, relPath, line, messages.SeverityNiveis.error));
    }
    return ocorrencias;
}
export const analistaRustSeguranca = criarAnalista({
    nome: 'analista-rust-seguranca',
    categoria: 'seguranca',
    descricao: 'Detecta problemas de segurança e unsafe em código Rust.',
    global: false,
    test: (relPath) => /\.(rs)$/i.test(relPath),
    aplicar: async (src, relPath) => {
        if (disableEnv)
            return null;
        const msgs = collectSecurityIssues(src, relPath);
        return msgs.length ? msgs : null;
    }
});
//# sourceMappingURL=analyst-security.js.map