import { config } from '../core/config/index.js';
import { getMessages } from '../core/messages/index.js';
import { carregarBaseline, diffSnapshots, gerarSnapshotDoConteudo, LINHA_BASE_CAMINHO, salvarBaseline, verificarErros } from './index.js';
import { ensureDir, normalizePath } from '../shared/helpers/index.js';
import micromatch from 'micromatch';
import { GuardianError, IntegridadeStatus } from '../types/index.js';
const { log, GuardianMensagens } = getMessages();
function getErrMsg(err) {
    return typeof err === 'object' && err && 'message' in err ? err.message : String(err);
}
async function construirSnapshot(fileEntries) {
    const snapshot = {};
    for (const { relPath, content } of fileEntries) {
        if (typeof content !== 'string' || !content.trim())
            continue;
        try {
            snapshot[relPath] = await gerarSnapshotDoConteudo(content);
        }
        catch (err) {
            log.aviso(`\u001Fx Falha ao gerar assinatura GPG de ${relPath}: ${getErrMsg(err)}`);
        }
    }
    return snapshot;
}
export async function scanSystemIntegrity(fileEntries, options) {
    const agora = new Date().toISOString();
    await ensureDir(LINHA_BASE_CAMINHO);
    let baselineAnterior = null;
    try {
        baselineAnterior = await carregarBaseline();
    }
    catch (err) {
        log.aviso(GuardianMensagens.baselineInvalido(getErrMsg(err)));
    }
    const ignorados = config.INCLUDE_EXCLUDE_RULES && config.INCLUDE_EXCLUDE_RULES.globalExcludeGlob || [];
    const filtrados = fileEntries.filter(arquivo => {
        const rel = normalizePath(arquivo.relPath);
        return !micromatch.isMatch(rel, ignorados);
    });
    if (config.DEV_MODE) {
        const removidos = fileEntries.length - filtrados.length;
        log.info(GuardianMensagens.filtroAplicado(filtrados.length, removidos));
    }
    const { gerarSnapshotDoConteudo: gerar } = await import('./hash.js');
    const snapshotAtual = {};
    for (const { relPath, content } of filtrados) {
        if (typeof content !== 'string' || !content.trim())
            continue;
        try {
            snapshotAtual[relPath] = await gerar(content);
        }
        catch (err) {
            log.aviso(`\u001Fx Falha ao gerar assinatura GPG de ${relPath}: ${getErrMsg(err)}`);
        }
    }
    if (!baselineAnterior) {
        if (options?.justDiff) {
            return {
                status: IntegridadeStatus.Ok,
                timestamp: agora,
                detalhes: []
            };
        }
        if (!options?.suppressLogs) {
            log.info(GuardianMensagens.baselineInicialCriado);
        }
        await salvarBaseline(snapshotAtual);
        return {
            status: IntegridadeStatus.Criado,
            timestamp: agora
        };
    }
    if (process.argv.includes('--aceitar')) {
        if (!options?.suppressLogs) {
            log.info(GuardianMensagens.baselineAceitoManualmente);
        }
        await salvarBaseline(snapshotAtual);
        return {
            status: IntegridadeStatus.Aceito,
            timestamp: agora
        };
    }
    const diffs = diffSnapshots(baselineAnterior, snapshotAtual);
    const erros = verificarErros(diffs);
    if (options?.justDiff) {
        return {
            status: erros.length ? IntegridadeStatus.AlteracoesDetectadas : IntegridadeStatus.Ok,
            timestamp: agora,
            detalhes: erros
        };
    }
    if (erros.length) {
        throw new GuardianError(erros.map(erro => ({
            tipo: 'integridade',
            mensagem: erro
        })));
    }
    return {
        status: IntegridadeStatus.Ok,
        timestamp: agora
    };
}
export async function acceptNewBaseline(fileEntries) {
    const ignorados = [];
    const ignoradosDyn = config.INCLUDE_EXCLUDE_RULES && config.INCLUDE_EXCLUDE_RULES.globalExcludeGlob || ignorados;
    const filtrados = fileEntries.filter(arquivo => {
        const rel = normalizePath(arquivo.relPath);
        return !micromatch.isMatch(rel, ignoradosDyn);
    });
    const snapshotAtual = await construirSnapshot(filtrados);
    await ensureDir(LINHA_BASE_CAMINHO);
    await salvarBaseline(snapshotAtual);
}
//# sourceMappingURL=sentinel.js.map