import path from 'node:path';
import { detectarFantasmas } from '../detectors/index.js';
import { config } from '../../core/config/index.js';
import { getMessages } from '../../core/messages/index.js';
import { gerarRelatorioPodaJson, gerarRelatorioPodaMarkdown } from '../../reports/index.js';
import { ensureDir } from '../../shared/helpers/index.js';
import { lerEstado, salvarEstado } from '../../shared/persistence/index.js';
import pLimit from 'p-limit';
const { log, logAuto } = getMessages();
export async function removerArquivosOrfaos(_fileEntries) {
    const { fantasmas } = await detectarFantasmas();
    return {
        arquivosOrfaos: fantasmas
    };
}
function gerarPendencias(fantasmas, agora) {
    return fantasmas.map(arquivo => ({
        arquivo: arquivo.arquivo,
        motivo: arquivo.referenciado ? 'inativo' : 'órfão',
        detectedAt: agora,
        scheduleAt: agora
    }));
}
function mesclarPendencias(anteriores, novos) {
    const mapa = new Map();
    for (const caminho of anteriores)
        mapa.set(caminho.arquivo, caminho);
    for (const caminho of novos)
        mapa.set(caminho.arquivo, caminho);
    return Array.from(mapa.values());
}
function dividirPendencias(pendencias, reativar, _agora) {
    const aManter = [];
    const aPodar = [];
    const reativarSet = new Set(reativar);
    for (const caminho of pendencias) {
        if (reativarSet.has(caminho.arquivo)) {
            aManter.push(caminho);
        }
        else {
            aPodar.push(caminho);
        }
    }
    return [aManter, aPodar];
}
const { AUTOANALISE_CONCURRENCY: CONCORRENCIA = 5, ZELADOR_ABANDONED_DIR: DIR_ABANDONADOS, ZELADOR_PENDING_PATH: PATH_PENDENTES, ZELADOR_REACTIVATE_PATH: PATH_REATIVAR, ZELADOR_HISTORY_PATH: PATH_HISTORICO, ZELADOR_REPORT_PATH: PATH_RELATORIO } = config;
export async function executarPodaCiclica(executarRealmente = false) {
    log.info('\n[HERB] Iniciando poda automática...\n');
    if (!executarRealmente) {
        log.aviso('[TEST] Modo de simulação ativado (SIMULADO). Nenhum arquivo será movido.\n');
    }
    const base = process.cwd();
    const agora = Date.now();
    const [anteriores, reativar, historico] = await Promise.all([lerEstado(PATH_PENDENTES), lerEstado(PATH_REATIVAR), lerEstado(PATH_HISTORICO)]);
    const { fantasmas } = await detectarFantasmas();
    const novos = gerarPendencias(fantasmas, agora);
    const unicos = mesclarPendencias(anteriores, novos);
    const [aManter, aPodar] = dividirPendencias(unicos, reativar, agora);
    if (!aPodar.length) {
        logAuto.podaNenhumArquivo();
        await gerarRelatorioPodaMarkdown(PATH_RELATORIO.replace(/\.json$/, '.md'), aPodar, aManter, {
            simulado: !executarRealmente
        });
        await gerarRelatorioPodaJson(PATH_RELATORIO, aPodar, aManter);
        return;
    }
    if (executarRealmente) {
        logAuto.podaPodando(aPodar.length);
        await moverArquivos(aPodar, base, historico);
        await salvarEstado(PATH_PENDENTES, aManter);
        await salvarEstado(PATH_HISTORICO, historico);
        log.sucesso('[BROOM] Podagem concluída.');
    }
    else {
        logAuto.podaPodandoSimulado(aPodar.length);
        moverArquivosSimulado(aPodar, base);
    }
}
function moverArquivosSimulado(lista, base) {
    log.info(`Simulando movimentação para ${DIR_ABANDONADOS}:\n`);
    for (const pendencia of lista) {
        const destino = path.join(base, DIR_ABANDONADOS, pendencia.arquivo);
        log.info(`  → SIMULADO: '${pendencia.arquivo}' → '${path.relative(base, destino)}'`);
    }
    log.info('');
}
async function moverArquivos(lista, base, historico) {
    const limitar = pLimit(CONCORRENCIA);
    await Promise.all(lista.map(pend => limitar(async () => {
        const src = path.join(base, pend.arquivo);
        const dest = path.join(base, DIR_ABANDONADOS, pend.arquivo);
        try {
            const fs = await import('node:fs');
            await ensureDir(dest);
            await fs.promises.rename(src, dest);
            historico.push({
                arquivo: pend.arquivo,
                movidoEm: new Date().toISOString(),
                motivo: pend.motivo
            });
            logAuto.podaArquivoMovido(pend.arquivo);
        }
        catch (err) {
            log.erro(`[ERRO] Falha ao mover ${pend.arquivo}: ${typeof err === 'object' && err && 'message' in err ? err.message : String(err)}`);
        }
    })));
}
//# sourceMappingURL=pruning.js.map