import { criarOcorrencia } from '../../types/index.js';
export const analistaRecomendacaoArquitetura = {
    nome: 'recomendacao-arquitetura',
    categoria: 'arquitetura',
    descricao: 'Analisa o projeto e recomenda a melhor arquitetura a ser aplicada',
    global: true,
    test: () => true,
    aplicar: async (_src, _relPath, _ast, _fullCaminho, contexto) => {
        if (!contexto)
            return [];
        const ocorrencias = [];
        const caminhos = contexto.arquivos.map(a => a.relPath.toLowerCase());
        const conteudos = contexto.arquivos.map(a => a.content?.toLowerCase() || '');
        let scoreCleanArch = 0;
        const sinaisCleanArch = [];
        const temEntities = caminhos.some(c => c.includes('/entities/') || c.endsWith('entity.ts') || c.endsWith('entity.js'));
        const temValueObjects = caminhos.some(c => c.includes('value-object') || c.includes('value_object'));
        const temDomainServices = caminhos.some(c => c.includes('/domain/') && c.includes('service'));
        const temDomainEvents = caminhos.some(c => c.includes('domain-event') || c.includes('domain_events'));
        if (temEntities) {
            scoreCleanArch += 15;
            sinaisCleanArch.push('Entidades de domínio');
        }
        if (temValueObjects) {
            scoreCleanArch += 10;
            sinaisCleanArch.push('Value Objects');
        }
        if (temDomainServices) {
            scoreCleanArch += 10;
            sinaisCleanArch.push('Serviços de domínio');
        }
        if (temDomainEvents) {
            scoreCleanArch += 10;
            sinaisCleanArch.push('Eventos de domínio');
        }
        const temUseCases = caminhos.some(c => c.includes('/use-cases') || c.includes('/usecases') || c.includes('/application/'));
        const temPorts = caminhos.some(c => c.includes('/ports/') || c.includes('/application/port'));
        const temDtos = caminhos.some(c => c.includes('/dto/') || c.endsWith('.dto.ts') || c.endsWith('.dto.js'));
        if (temUseCases) {
            scoreCleanArch += 15;
            sinaisCleanArch.push('Casos de uso (use-cases)');
        }
        if (temPorts) {
            scoreCleanArch += 10;
            sinaisCleanArch.push('Ports');
        }
        if (temDtos) {
            scoreCleanArch += 10;
            sinaisCleanArch.push('DTOs');
        }
        const temInfra = caminhos.some(c => c.includes('/infrastructure/') || c.includes('/infra/'));
        const temRepositories = caminhos.some(c => c.includes('/repositories/') || c.endsWith('.repository.ts'));
        const temGateways = caminhos.some(c => c.includes('/gateways/'));
        if (temInfra) {
            scoreCleanArch += 10;
            sinaisCleanArch.push('Camada de infraestrutura');
        }
        if (temRepositories) {
            scoreCleanArch += 10;
            sinaisCleanArch.push('Implementações de repositório');
        }
        if (temGateways) {
            scoreCleanArch += 5;
            sinaisCleanArch.push('Gateways');
        }
        const temControllers = caminhos.some(c => c.includes('/controllers/') || c.endsWith('.controller.ts'));
        const temPresenters = caminhos.some(c => c.includes('/presenters/') || c.endsWith('.presenter.ts'));
        if (temControllers) {
            scoreCleanArch += 10;
            sinaisCleanArch.push('Controllers');
        }
        if (temPresenters) {
            scoreCleanArch += 5;
            sinaisCleanArch.push('Presenters');
        }
        const temDI = conteudos.some(c => c.includes('tsyringe') || c.includes('inversify') || c.includes('awilix') || c.includes('typedi'));
        if (temDI) {
            scoreCleanArch += 5;
            sinaisCleanArch.push('Container DI');
        }
        let scoreDistributed = 0;
        const sinaisDistributed = [];
        const servicosSet = new Set();
        for (const c of caminhos) {
            const match = c.match(/services\/([^/]+)/);
            if (match)
                servicosSet.add(match[1]);
        }
        if (servicosSet.size >= 2) {
            scoreDistributed += 20;
            sinaisDistributed.push(`${servicosSet.size} boundaries de serviço`);
        }
        else if (servicosSet.size === 1) {
            scoreDistributed += 10;
            sinaisDistributed.push('1 boundary de serviço');
        }
        const temMensageria = caminhos.some(c => c.includes('/events/') || c.includes('/messaging') || c.includes('/queues') ||
            c.includes('/consumers') || c.includes('/producers'));
        const temMensageriaDeps = conteudos.some(c => c.includes('kafkajs') || c.includes('amqplib') || c.includes('ioredis') ||
            c.includes('bull') || c.includes('bullmq') || c.includes('nats'));
        if (temMensageria || temMensageriaDeps) {
            scoreDistributed += 15;
            sinaisDistributed.push('Mensageria');
        }
        const temGateway = caminhos.some(c => c.includes('/gateway') || c.includes('/api-gateway'));
        if (temGateway) {
            scoreDistributed += 15;
            sinaisDistributed.push('API Gateway');
        }
        const temDiscovery = caminhos.some(c => c.includes('/discovery') || c.includes('consul') || c.includes('eureka'));
        if (temDiscovery) {
            scoreDistributed += 10;
            sinaisDistributed.push('Service Discovery');
        }
        const temDocker = caminhos.some(c => c.endsWith('dockerfile') || c.includes('docker-compose'));
        if (temDocker) {
            scoreDistributed += 10;
            sinaisDistributed.push('Docker');
        }
        const temK8s = caminhos.some(c => c.includes('kubernetes') || c.includes('k8s/'));
        if (temK8s) {
            scoreDistributed += 10;
            sinaisDistributed.push('Kubernetes');
        }
        const temEventDriven = conteudos.filter(c => c.includes('eventemitter') || c.includes('publish') || c.includes('subscribe') ||
            c.includes('webhook') || c.includes('observable')).length > 3;
        if (temEventDriven) {
            scoreDistributed += 10;
            sinaisDistributed.push('Padrões event-driven');
        }
        const temMonitoring = caminhos.some(c => c.includes('/health') || c.includes('/monitoring') || c.includes('/metrics'));
        if (temMonitoring) {
            scoreDistributed += 10;
            sinaisDistributed.push('Monitoramento');
        }
        const temShared = caminhos.some(c => c.includes('/shared/') || c.includes('/common/'));
        if (temShared) {
            scoreDistributed += 5;
            sinaisDistributed.push('Biblioteca compartilhada');
        }
        const totalArquivos = contexto.arquivos.length;
        const complexidadeBaixa = totalArquivos < 30;
        const temFrontend = caminhos.some(c => c.includes('/pages/') || c.includes('/components/') || c.includes('/views/'));
        let arquiteturaRecomendada = 'Arquitetura Simples / Monolítica';
        let melhorScore = 0;
        let confianca = 0;
        const recomendacoes = [];
        if (scoreCleanArch >= 40 || (temEntities && temUseCases)) {
            if (scoreCleanArch > melhorScore) {
                arquiteturaRecomendada = 'Clean Architecture (Arquitetura Limpa)';
                melhorScore = scoreCleanArch;
                confianca = Math.min(95, scoreCleanArch + (temDI ? 10 : 0));
            }
            if (!temEntities)
                recomendacoes.push('Crie entidades de domínio para encapsular regras de negócio');
            if (!temUseCases)
                recomendacoes.push('Organize a lógica da aplicação em casos de uso (use-cases)');
            if (!temPorts)
                recomendacoes.push('Defina portas (ports) na camada de aplicação para inversão de dependência');
            if (!temRepositories)
                recomendacoes.push('Implemente o padrão Repository para abstrair persistência');
        }
        if (scoreDistributed >= 35 && servicosSet.size >= 1) {
            if (scoreDistributed > melhorScore) {
                arquiteturaRecomendada = 'Arquitetura Distribuída / Microsserviços';
                melhorScore = scoreDistributed;
                confianca = Math.min(95, scoreDistributed);
            }
            if (!temMensageria && !temMensageriaDeps) {
                recomendacoes.push('Adicione mensageria (Kafka, RabbitMQ) para comunicação assíncrona entre serviços');
            }
            if (!temGateway && servicosSet.size > 1) {
                recomendacoes.push('Implemente um API Gateway para rotear requisições aos serviços');
            }
            if (!temDocker)
                recomendacoes.push('Conteinerize os serviços com Docker');
            if (!temMonitoring)
                recomendacoes.push('Adicione health checks e monitoramento centralizado');
        }
        if (temFrontend && temControllers && !temEntities) {
            const scoreMvc = (temControllers ? 15 : 0) + (temFrontend ? 15 : 0);
            if (scoreMvc > melhorScore && !complexidadeBaixa) {
                arquiteturaRecomendada = 'MVC (Model-View-Controller)';
                melhorScore = scoreMvc;
                confianca = Math.min(80, scoreMvc + 30);
            }
        }
        if (melhorScore === 0) {
            if (complexidadeBaixa) {
                arquiteturaRecomendada = 'Arquitetura Simples / Monolítica';
                confianca = 60;
                recomendacoes.push('Projeto de baixa complexidade - comece com uma estrutura simples');
                recomendacoes.push('Considere evoluir para Clean Architecture conforme o projeto crescer');
            }
            else if (temFrontend) {
                arquiteturaRecomendada = 'Arquitetura Modular';
                confianca = 50;
                recomendacoes.push('Organize o projeto em módulos por funcionalidade');
            }
            else {
                arquiteturaRecomendada = 'Arquitetura em Camadas';
                confianca = 50;
                recomendacoes.push('Organize o código em camadas (controllers, services, repositories)');
            }
        }
        if (scoreCleanArch >= 20 && scoreDistributed >= 20) {
            recomendacoes.push('Projeto apresenta características híbridas - considere Clean Architecture com boundaries de microsserviços');
        }
        if (totalArquivos > 100 && servicosSet.size === 0) {
            recomendacoes.push('Projeto grande e monolítico - considere dividir em serviços menores');
        }
        ocorrencias.push(criarOcorrencia({
            tipo: 'recomendacao-arquitetura',
            nivel: 'info',
            relPath: _relPath,
            linha: 1,
            mensagem: `[TARGET] Arquitetura recomendada: ${arquiteturaRecomendada} (${confianca}% confiança)`
        }));
        if (sinaisCleanArch.length > 0) {
            ocorrencias.push(criarOcorrencia({
                tipo: 'sinais-clean-arch',
                nivel: 'info',
                relPath: _relPath,
                linha: 1,
                mensagem: `Sinais de Clean Architecture: ${sinaisCleanArch.join(', ')}`
            }));
        }
        if (sinaisDistributed.length > 0) {
            ocorrencias.push(criarOcorrencia({
                tipo: 'sinais-distributed-arch',
                nivel: 'info',
                relPath: _relPath,
                linha: 1,
                mensagem: `Sinais de Arquitetura Distribuída: ${sinaisDistributed.join(', ')}`
            }));
        }
        for (const rec of recomendacoes.slice(0, 5)) {
            ocorrencias.push(criarOcorrencia({
                tipo: 'recomendacao-arquitetura-item',
                nivel: 'info',
                relPath: _relPath,
                linha: 1,
                mensagem: `[IDEA] ${rec}`
            }));
        }
        return ocorrencias;
    }
};
//# sourceMappingURL=detector-recommendation-architecture.js.map