import { traverse } from '../../../core/config/index.js';
import { messages } from '../../../core/messages/index.js';
import { shouldSuppressOccurrence } from '../../../shared/helpers/index.js';
import { criarOcorrencia } from '../../../types/index.js';
const visitorMemoria = {
    CallExpression(path, state) {
        const callee = path.node.callee;
        if (callee.type === 'Identifier') {
            if (callee.name === 'setInterval') {
                const parent = path.parent;
                if (parent.type !== 'VariableDeclarator' && parent.type !== 'AssignmentExpression') {
                    const occurrences = state.ocorrencias || [];
                    occurrences.push({
                        tipo: 'setinterval-unassigned',
                        linha: path.node.loc?.start.line || 0,
                        coluna: path.node.loc?.start.column || 0,
                        severidade: 'media',
                        nivel: 'aviso',
                        mensagem: messages.DetectorJsTsMensagens.setIntervalUnassigned,
                        relPath: state.relPath
                    });
                }
            }
        }
        else if (callee.type === 'MemberExpression') {
            const prop = callee.property;
            const propName = prop.type === 'Identifier' ? prop.name : '';
            if (propName === 'setInterval' && callee.object.type === 'Identifier' && callee.object.name === 'window') {
                const parent = path.parent;
                if (parent.type !== 'VariableDeclarator' && parent.type !== 'AssignmentExpression') {
                    const occurrences = state.ocorrencias || [];
                    occurrences.push({
                        tipo: 'setinterval-unassigned',
                        linha: path.node.loc?.start.line || 0,
                        coluna: path.node.loc?.start.column || 0,
                        severidade: 'media',
                        nivel: 'aviso',
                        mensagem: messages.DetectorJsTsMensagens.windowSetIntervalUnassigned,
                        relPath: state.relPath
                    });
                }
            }
            if (propName === 'addEventListener') {
                const isGlobal = callee.object.type === 'Identifier' && ['window', 'document', 'body'].includes(callee.object.name);
                if (isGlobal && state.contextType === 'react') {
                    state.hasGlobalListeners = true;
                }
            }
        }
    }
};
export const analistaVazamentoMemoria = {
    nome: 'vazamento-memoria',
    categoria: 'code-quality',
    descricao: 'Heurísticas para detecção de vazamentos de memória (setInterval não limpo, eventListeners globais pendentes)',
    visitor: visitorMemoria,
    test: (relPath) => {
        return /\.(js|jsx|ts|tsx)$/.test(relPath) && !/\.test\.(ts|js)$/.test(relPath);
    },
    aplicar: async (src, relPath, ast) => {
        if (!ast)
            return [];
        if (shouldSuppressOccurrence('vazamento-memoria', relPath)) {
            return [];
        }
        const isReact = /\.(jsx|tsx)$/.test(relPath) || src.includes('react');
        const stateObj = {
            ocorrencias: [],
            relPath,
            contextType: isReact ? 'react' : 'vanilla',
            hasGlobalListeners: false
        };
        const nodeToTraverse = ('node' in ast ? ast.node : ast);
        traverse(nodeToTraverse, visitorMemoria, undefined, stateObj);
        if (stateObj.hasGlobalListeners && stateObj.contextType === 'react') {
            if (!src.includes('removeEventListener')) {
                stateObj.ocorrencias.push({
                    tipo: 'global-listener-no-cleanup',
                    linha: 1,
                    coluna: 0,
                    severidade: 'alta',
                    nivel: 'erro',
                    mensagem: messages.DetectorJsTsMensagens.globalListenerNoCleanup,
                    relPath
                });
            }
        }
        return stateObj.ocorrencias.map(ocorrencia => criarOcorrencia({
            tipo: ocorrencia.tipo ?? 'vazamento-memoria',
            nivel: ocorrencia.nivel || 'aviso',
            mensagem: ocorrencia.mensagem,
            linha: ocorrencia.linha || 0,
            relPath,
            origem: 'vazamento-memoria'
        }));
    }
};
//# sourceMappingURL=detector-leaks-memory.js.map