import { messages } from '../../core/messages/index.js';
import { formatarMarkdownMinimo, formatarPrettierMinimo } from '../../shared/formatters/index.js';
import { extrairSupressoes, shouldSuppressOccurrence } from '../../shared/helpers/index.js';
import { criarAnalista, criarOcorrencia } from '../../types/index.js';
const disableEnv = process.env.TUTANUS_DISABLE_PLUGIN_FORMATADOR === '1';
function parserParaTipo(parser) {
    return `formatador-${parser}`;
}
function msg(message, relPath, parser, nivel = messages.SeverityNiveis.warning, line = 1) {
    return criarOcorrencia({
        relPath,
        mensagem: message,
        linha: line,
        nivel,
        origem: messages.AnalystOrigens.formatador,
        tipo: parserParaTipo(parser)
    });
}
function normalizarEol(code) {
    return code.replace(/\r\n?/g, '\n');
}
function primeiraLinhaDiferente(arquivo, base) {
    const aLines = normalizarEol(arquivo).split('\n');
    const bLines = normalizarEol(base).split('\n');
    const len = Math.max(aLines.length, bLines.length);
    for (let indice = 0; indice < len; indice++) {
        if ((aLines[indice] ?? '') !== (bLines[indice] ?? ''))
            return indice + 1;
    }
    return 1;
}
function extrairLinhasProtegidas(src) {
    const supressoes = extrairSupressoes(src);
    const protegidas = new Set();
    for (const [linha, regras] of supressoes.porLinha) {
        if (regras.has('pontuacao-repetida') || regras.has('espacamento-incorreto') || regras.has('*') || regras.has('analista-formatador')) {
            protegidas.add(linha);
        }
    }
    return protegidas;
}
export const analistaFormatador = criarAnalista({
    nome: 'analista-formatador',
    categoria: 'formatacao',
    descricao: 'Verifica formatação mínima interna do Tutanus (JSON/Markdown/YAML).',
    global: false,
    test: (relPath) => {
        if (/package-lock\.json$/i.test(relPath) || /yarn\.lock$/i.test(relPath) || /pnpm-lock\.yaml$/i.test(relPath))
            return false;
        return /\.(json|md|markdown|ya?ml)$/i.test(relPath);
    },
    aplicar: async (src, relPath) => {
        if (disableEnv)
            return null;
        const isMarkdown = /\.(md|markdown)$/i.test(relPath);
        let res;
        if (isMarkdown) {
            const protectedLines = extrairLinhasProtegidas(src);
            res = formatarMarkdownMinimo(src, protectedLines.size > 0 ? protectedLines : undefined);
        }
        else {
            res = formatarPrettierMinimo({
                code: src,
                relPath
            });
        }
        if (!res.ok) {
            const tipo = parserParaTipo(res.parser);
            if (shouldSuppressOccurrence(tipo, relPath))
                return null;
            return [msg(messages.FormatadorMensagens.parseErro(res.parser, res.error), relPath, res.parser, messages.SeverityNiveis.error, 1)];
        }
        if (!res.changed)
            return null;
        const tipo = parserParaTipo(res.parser);
        if (shouldSuppressOccurrence(tipo, relPath))
            return null;
        const linha = primeiraLinhaDiferente(src, res.formatted);
        const detalhes = [`primeira diferença na linha ${linha}`, res.reason ? `motivo: ${res.reason}` : null].filter(Boolean).join(', ');
        return [msg(messages.FormatadorMensagens.naoFormatado(res.parser, detalhes || undefined), relPath, res.parser, messages.SeverityNiveis.warning, linha)];
    }
});
//# sourceMappingURL=analyst-formatter.js.map