import { splitLines } from '../../../shared/helpers/index.js';
import { criarOcorrencia } from '../../../types/index.js';
export const detectorSqlBestPractices = {
    nome: 'detector-sql-best-practices',
    categoria: 'database',
    descricao: 'Detecta más práticas em SQL',
    test: (relPath) => /\.(sql|pgsql|mysql|sqlite)$/i.test(relPath),
    aplicar: (src, relPath) => {
        if (!src)
            return [];
        const ocorrencias = [];
        const linhas = splitLines(src);
        linhas.forEach((linha, index) => {
            const numeroLinha = index + 1;
            const linhaTrim = linha.trim().toLowerCase();
            if (/^\s*(delete|update)\s+/.test(linhaTrim) && !linhaTrim.includes('where')) {
                const proximaLinha = linhas[index + 1]?.trim().toLowerCase() || '';
                if (!proximaLinha.includes('where')) {
                    ocorrencias.push(criarOcorrencia({
                        tipo: 'sql-missing-where',
                        nivel: 'erro',
                        mensagem: 'DELETE/UPDATE sem cláusula WHERE',
                        relPath,
                        linha: numeroLinha,
                        sugestao: 'Adicione WHERE para restringir o impacto'
                    }));
                }
            }
            if (/\bselect\s+\*\s+from\b/i.test(linha)) {
                ocorrencias.push(criarOcorrencia({
                    tipo: 'sql-select-star',
                    nivel: 'aviso',
                    mensagem: 'SELECT * detectado',
                    relPath,
                    linha: numeroLinha,
                    sugestao: 'Liste explicitamente as colunas necessárias'
                }));
            }
            if (/\b(password|senha|secret|key|token)\b\s*[:=]\s*['"].*['"]/i.test(linha) ||
                /identified\s+by\s+['"].*['"]/i.test(linha)) {
                ocorrencias.push(criarOcorrencia({
                    tipo: 'sql-hardcoded-credential',
                    nivel: 'erro',
                    mensagem: 'Credencial hardcoded em SQL',
                    relPath,
                    linha: numeroLinha,
                    sugestao: 'Use variáveis de ambiente ou secrets manager'
                }));
            }
            if (/\btruncate\s+table\b/i.test(linha)) {
                ocorrencias.push(criarOcorrencia({
                    tipo: 'sql-truncate',
                    nivel: 'aviso',
                    mensagem: 'TRUNCATE TABLE detectado - operação irreversível',
                    relPath,
                    linha: numeroLinha,
                    sugestao: 'Use DELETE com WHERE se precisar de reversibilidade'
                }));
            }
            if (/create\s+(table|procedure|view)\s+\w+/i.test(linha) && !/if\s+not\s+exists/i.test(linha)) {
                ocorrencias.push(criarOcorrencia({
                    tipo: 'sql-missing-if-not-exists',
                    nivel: 'info',
                    mensagem: 'CREATE sem IF NOT EXISTS',
                    relPath,
                    linha: numeroLinha,
                    sugestao: 'Use CREATE ... IF NOT EXISTS para idempotência'
                }));
            }
            if (/\bvarchar\b\s*(\(|\s|$)/i.test(linha) && !/\bvarchar\(\d+\)/i.test(linha)) {
                ocorrencias.push(criarOcorrencia({
                    tipo: 'sql-varchar-without-size',
                    nivel: 'info',
                    mensagem: 'VARCHAR sem tamanho definido',
                    relPath,
                    linha: numeroLinha,
                    sugestao: 'Defina tamanho máximo: VARCHAR(255)'
                }));
            }
        });
        return ocorrencias;
    }
};
//# sourceMappingURL=detector-sql-best-practices.js.map