import path from 'node:path';
import { getMessages } from '../core/messages/index.js';
import { salvarEstado } from '../shared/persistence/index.js';
const { log, MENSAGENS_RELATORIOS_ANALISE, RelatorioAsyncPatternsMensagens } = getMessages();
function categorizarArquivo(relPath) {
    if (relPath.includes('cli/'))
        return 'cli';
    if (relPath.includes('analistas/'))
        return 'analistas';
    if (relPath.includes('core/') || relPath.includes('nucleo/'))
        return 'core';
    if (relPath.includes('guardian/'))
        return 'guardian';
    if (relPath.includes('auto/') || relPath.includes('zeladores/'))
        return 'auto';
    return 'outros';
}
function extrairTotalPromises(mensagem) {
    const match = mensagem.match(/\((\d+) mais\)/);
    if (match) {
        return parseInt(match[1], 10) + 1;
    }
    return 1;
}
function agruparPorArquivo(ocorrencias) {
    const porArquivo = new Map();
    for (const issue of ocorrencias) {
        const arquivo = issue.relPath;
        if (!porArquivo.has(arquivo)) {
            porArquivo.set(arquivo, {
                ocorrencias: [],
                nivel: (issue.nivel || 'info'),
                total: 0
            });
        }
        const info = porArquivo.get(arquivo);
        if (!info)
            continue;
        info.ocorrencias.push({
            linha: issue.linha,
            mensagem: issue.mensagem,
            nivel: (issue.nivel || 'info')
        });
        info.total += extrairTotalPromises(issue.mensagem);
    }
    return porArquivo;
}
export async function analisarAsyncPatterns(ocorrencias, options = {}) {
    const topN = options.topN || 20;
    const asyncIssues = ocorrencias.filter(ocorrencia => ocorrencia.mensagem && ocorrencia.mensagem.includes('unhandled-async'));
    log.info(MENSAGENS_RELATORIOS_ANALISE.asyncPatterns.titulo);
    log.info(RelatorioAsyncPatternsMensagens.totalOcorrencias.replace('{total}', String(asyncIssues.length)));
    const porArquivo = agruparPorArquivo(asyncIssues);
    const arquivosOrdenados = Array.from(porArquivo.entries()).map(([arquivo, info]) => ({
        arquivo,
        total: info.total,
        nivel: (info.nivel || 'info')
    })).sort((arquivo, base) => base.total - arquivo.total);
    log.info(RelatorioAsyncPatternsMensagens.topArquivos.replace('{total}', String(Math.min(topN, arquivosOrdenados.length))));
    for (let indice = 0; indice < Math.min(topN, arquivosOrdenados.length); indice++) {
        const { arquivo, total, nivel } = arquivosOrdenados[indice];
        const nivelIcon = nivel === 'erro' ? '[RED]' : nivel === 'aviso' ? '[AVISO]' : '[INFO]';
        log.info(`${indice + 1}. ${nivelIcon} ${arquivo}`);
        log.info(RelatorioAsyncPatternsMensagens.promiseSemTratamento.replace('{total}', String(total)));
        log.info(RelatorioAsyncPatternsMensagens.prioridade.replace('{nivel}', nivel.toUpperCase()));
    }
    const categorias = {
        cli: {
            totalArquivos: 0,
            totalPromises: 0
        },
        analistas: {
            totalArquivos: 0,
            totalPromises: 0
        },
        core: {
            totalArquivos: 0,
            totalPromises: 0
        },
        guardian: {
            totalArquivos: 0,
            totalPromises: 0
        },
        auto: {
            totalArquivos: 0,
            totalPromises: 0
        },
        outros: {
            totalArquivos: 0,
            totalPromises: 0
        }
    };
    for (const { arquivo, total } of arquivosOrdenados) {
        const categoria = categorizarArquivo(arquivo);
        categorias[categoria].totalArquivos++;
        categorias[categoria].totalPromises += total;
    }
    log.info(RelatorioAsyncPatternsMensagens.distribuicaoCategoria);
    for (const [cat, stats] of Object.entries(categorias)) {
        if (stats.totalArquivos > 0) {
            log.info(RelatorioAsyncPatternsMensagens.categoriaStats.replace('{categoria}', cat.toUpperCase()).replace('{arquivos}', String(stats.totalArquivos)).replace('{promises}', String(stats.totalPromises)));
        }
    }
    if (options.includeRecomendacoes !== false) {
        const criticos = arquivosOrdenados.filter(arquivo => arquivo.nivel === 'erro');
        const altos = arquivosOrdenados.filter(arquivo => arquivo.nivel === 'aviso');
        log.info(MENSAGENS_RELATORIOS_ANALISE.asyncPatterns.recomendacoes);
        if (criticos.length > 0) {
            log.info(MENSAGENS_RELATORIOS_ANALISE.asyncPatterns.critico);
            for (const { arquivo } of criticos.slice(0, 5)) {
                log.info(`   - ${arquivo}`);
            }
        }
        if (altos.length > 0) {
            log.info(MENSAGENS_RELATORIOS_ANALISE.asyncPatterns.alto);
            for (const { arquivo } of altos.slice(0, 10)) {
                log.info(`   - ${arquivo}`);
            }
        }
        log.info(RelatorioAsyncPatternsMensagens.proximosPassos);
        log.info(RelatorioAsyncPatternsMensagens.passo1);
        log.info(RelatorioAsyncPatternsMensagens.passo2);
        log.info(RelatorioAsyncPatternsMensagens.passo3);
        log.info(RelatorioAsyncPatternsMensagens.passo4);
    }
    const report = {
        timestamp: new Date().toISOString(),
        totalIssues: asyncIssues.length,
        totalFiles: porArquivo.size,
        topArquivos: arquivosOrdenados.slice(0, topN),
        categorias
    };
    if (options.includeRecomendacoes !== false) {
        const criticos = arquivosOrdenados.filter(arquivo => arquivo.nivel === 'erro');
        const altos = arquivosOrdenados.filter(arquivo => arquivo.nivel === 'aviso');
        report.recomendacoes = {
            criticos: criticos.slice(0, 5).map(arquivo => arquivo.arquivo),
            altos: altos.slice(0, 10).map(arquivo => arquivo.arquivo),
            proximosPassos: [RelatorioAsyncPatternsMensagens.passo1.replace('. ', ''), RelatorioAsyncPatternsMensagens.passo2.replace('. ', ''), RelatorioAsyncPatternsMensagens.passo3.replace('. ', ''), RelatorioAsyncPatternsMensagens.passo4.replace('. ', '')]
        };
    }
    return report;
}
export async function salvarRelatorioAsync(report, outputCaminho) {
    await salvarEstado(outputCaminho, report);
    log.sucesso(MENSAGENS_RELATORIOS_ANALISE.asyncPatterns.salvo(outputCaminho));
}
export async function executarAnaliseAsync(ocorrencias, baseDir, options = {}) {
    const report = await analisarAsyncPatterns(ocorrencias, options);
    const reportCaminho = path.join(baseDir, 'reports', 'async-analysis-report.json');
    await salvarRelatorioAsync(report, reportCaminho);
}
//# sourceMappingURL=analise-async-patterns.js.map