import { config } from '../../core/config/index.js';
import { getMessages } from '../../core/messages/index.js';
import { extrairSupressoes, isRegraSuprimida } from '../../shared/helpers/index.js';
const { log } = getMessages();
const LICENCA_PADROES = {
    incompativeis: [/\bGPL\b/i, /\bAGPL\b/i, /\bLGPL\b/i, /Creative\s+Commons/i, /\bCC-BY\b/i, /All\s+rights\s+reserved/i],
    cessaoDireitos: [/cess(?:ã|a)o\s+de\s+direitos/i, /transfer(?:ê|e)ncia\s+de\s+direitos/i],
    referenciasRisco: [/Stack\s*Overflow/i, /(?:^|https?:\/\/|\/\/)(?:[^\/\s@]+\.)?stackoverflow\.com(?::\d+)?(?:[\/?#]|$)/i, /\bassign\b/i, /\bcession\b/i]
};
const PADRAO_LISTA_BRANCA = {
    paths: ['.github/copilot-instructions.md', 'docs/POLICY-PROVENIENCIA.md', 'docs/partials/AVISO-PROVENIENCIA.md'],
    patterns: ['**/reports/**', 'docs/history/**', 'tests/**', 'tmp*.md'],
    dirs: ['pre-public', 'preview-tutanus', '.abandonados', '.deprecados', 'reports']
};
function createRiskRegex() {
    const allPadroes = [...LICENCA_PADROES.incompativeis, ...LICENCA_PADROES.cessaoDireitos, ...LICENCA_PADROES.referenciasRisco].map(raiz => raiz.source).join('|');
    return new RegExp(allPadroes, 'i');
}
function hasProvenienciaHeader(content, headerLines = 30) {
    const head = content.split(/\r?\n/).slice(0, headerLines).join('\n');
    return /Proveni[eê]ncia\s+e\s+Autoria/i.test(head);
}
function isWhitelisted(relPath, whitelist) {
    const normalized = relPath.replace(/\\/g, '/');
    if (whitelist.paths.some((caminho) => normalized === caminho || normalized.endsWith(`/${caminho}`))) {
        return true;
    }
    if (whitelist.dirs.some((dir) => normalized.startsWith(`${dir}/`))) {
        return true;
    }
    for (const pattern of whitelist.patterns) {
        if (pattern.includes('**')) {
            const parts = pattern.split('**');
            if (parts.every((part) => normalized.includes(part.replace(/\*/g, '')))) {
                return true;
            }
        }
        else if (pattern.startsWith('*')) {
            if (normalized.endsWith(pattern.substring(1))) {
                return true;
            }
        }
        else if (pattern.includes('*')) {
            const [prefix, suffix] = pattern.split('*');
            if (normalized.startsWith(prefix) && normalized.endsWith(suffix)) {
                return true;
            }
        }
    }
    return false;
}
function hasRiskReferenceMarker(content) {
    return /<!--\s*RISCO_REFERENCIA_OK\s*-->/i.test(content);
}
function hasTutanusIgnoreMarker(content, key) {
    const escaped = key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    const oldPattern = new RegExp(`<!--\\s*tutanus-ignore\\s*:\\s*${escaped}\\s*-->`, 'i');
    const newPattern = new RegExp(`<!--\\s*@tutanus-disable\\s+${escaped}(?:\\s|-->|$)`, 'i');
    return oldPattern.test(content) || newPattern.test(content);
}
function mergeWhitelist(base, override, mode) {
    const overrideConfig = override || {};
    if (mode === 'replace') {
        return {
            paths: Array.isArray(overrideConfig.paths) ? overrideConfig.paths : [],
            patterns: Array.isArray(overrideConfig.patterns) ? overrideConfig.patterns : [],
            dirs: Array.isArray(overrideConfig.dirs) ? overrideConfig.dirs : []
        };
    }
    const uniq = (arr) => Array.from(new Set(arr.map(String)));
    const overridePaths = Array.isArray(overrideConfig.paths) ? overrideConfig.paths : [];
    const overridePatterns = Array.isArray(overrideConfig.patterns) ? overrideConfig.patterns : [];
    const overrideDirs = Array.isArray(overrideConfig.dirs) ? overrideConfig.dirs : [];
    return {
        paths: uniq([...(base.paths || []), ...overridePaths]),
        patterns: uniq([...(base.patterns || []), ...overridePatterns]),
        dirs: uniq([...(base.dirs || []), ...overrideDirs])
    };
}
function isBenignProvenienciaOnly(content) {
    const rxCessao = /cess(?:ã|a)o\s+de\s+direitos/i;
    const rxOthers = new RegExp(['\\bGPL\\b', '\\bAGPL\\b', '\\bLGPL\\b', 'Creative\\s+Commons', '\\bCC-BY\\b', 'Stack\\s*Overflow', '(?:^|[^\\w.-])(?:[\\w-]+\\.)*stackoverflow\\.com(?:$|[^\\w.-])', 'All\\s+rights\\s+reserved', 'transfer(?:ê|e)ncia\\s+de\\s+direitos', '\\bassign\\b', '\\bcession\\b'].join('|'), 'i');
    const hasCessao = rxCessao.test(content);
    const hasOthers = rxOthers.test(content);
    const hasAviso = /Proveni[eê]ncia\s+e\s+Autoria/i.test(content);
    return hasAviso && hasCessao && !hasOthers;
}
async function analisarArquivoMarkdown(fullCaminho, relPath, content, options) {
    const whitelist = options.whitelist || PADRAO_LISTA_BRANCA;
    const problemas = [];
    const whitelisted = isWhitelisted(relPath, whitelist);
    const temRiscoOk = hasRiskReferenceMarker(content);
    const temProveniencia = hasProvenienciaHeader(content, options.headerLines || 30);
    const ignoreLicencaCheck = hasTutanusIgnoreMarker(content, 'license-check');
    if (options.checkProveniencia !== false && !temProveniencia && !whitelisted) {
        problemas.push({
            tipo: 'falta-proveniencia',
            descricao: 'Arquivo não possui aviso de Proveniência e Autoria nas primeiras linhas',
            severidade: 'alto',
            sugestao: 'Adicione o aviso usando scripts/add-disclaimer-md.js'
        });
    }
    if (options.checkLicenses !== false || options.checkReferences !== false) {
        const riskRegex = createRiskRegex();
        const hasRisk = riskRegex.test(content);
        if (hasRisk && !isBenignProvenienciaOnly(content) && !whitelisted && !temRiscoOk) {
            const lines = content.split(/\r?\n/);
            const supressoes = extrairSupressoes(content);
            for (let indice = 0; indice < lines.length; indice++) {
                const line = lines[indice];
                const linhaAtual = indice + 1;
                if (options.checkLicenses !== false && !ignoreLicencaCheck) {
                    for (const pattern of LICENCA_PADROES.incompativeis) {
                        if (pattern.test(line)) {
                            const regraNome = `markdown-licenca-incompativel`;
                            if (!isRegraSuprimida(regraNome, linhaAtual, supressoes) && !isRegraSuprimida('detector-markdown', linhaAtual, supressoes)) {
                                problemas.push({
                                    tipo: 'licenca-incompativel',
                                    descricao: `Licença potencialmente incompatível: ${pattern.source}`,
                                    severidade: 'critico',
                                    linha: linhaAtual,
                                    trecho: line.trim().substring(0, 100),
                                    sugestao: 'Verifique compatibilidade com licença MIT do projeto'
                                });
                            }
                        }
                    }
                }
                if (options.checkReferences !== false) {
                    for (const pattern of LICENCA_PADROES.cessaoDireitos) {
                        if (pattern.test(line)) {
                            const regraNome = `markdown-referencia-risco`;
                            if (!isRegraSuprimida(regraNome, linhaAtual, supressoes) && !isRegraSuprimida('detector-markdown', linhaAtual, supressoes)) {
                                problemas.push({
                                    tipo: 'referencia-risco',
                                    descricao: 'Referência a cessão de direitos detectada',
                                    severidade: 'alto',
                                    linha: linhaAtual,
                                    trecho: line.trim().substring(0, 100),
                                    sugestao: 'Verifique se não há implicações legais'
                                });
                            }
                        }
                    }
                    for (const pattern of LICENCA_PADROES.referenciasRisco) {
                        if (pattern.test(line)) {
                            const regraNome = `markdown-referencia-risco`;
                            if (!isRegraSuprimida(regraNome, linhaAtual, supressoes) && !isRegraSuprimida('detector-markdown', linhaAtual, supressoes)) {
                                problemas.push({
                                    tipo: 'referencia-risco',
                                    descricao: `Referência externa detectada: ${pattern.source}`,
                                    severidade: 'medio',
                                    linha: linhaAtual,
                                    trecho: line.trim().substring(0, 100),
                                    sugestao: 'Adicione marcador <!-- RISCO_REFERENCIA_OK --> se referência for válida'
                                });
                            }
                        }
                    }
                }
            }
        }
    }
    return {
        relPath,
        fullCaminho,
        problemas,
        temProveniencia,
        whitelisted,
        temRiscoOk
    };
}
function converterParaOcorrencias(analise) {
    const ocorrencias = [];
    for (const problema of analise.problemas) {
        let nivel;
        switch (problema.severidade) {
            case 'critico':
            case 'alto':
                nivel = 'erro';
                break;
            case 'medio':
                nivel = 'aviso';
                break;
            default:
                nivel = 'info';
        }
        ocorrencias.push({
            tipo: `markdown-${problema.tipo}`,
            nivel,
            mensagem: problema.descricao,
            relPath: analise.relPath,
            linha: problema.linha,
            contexto: problema.trecho,
            sugestao: problema.sugestao
        });
    }
    return ocorrencias;
}
export const detectorMarkdown = {
    nome: 'detector-markdown',
    categoria: 'documentacao',
    descricao: 'Detecta problemas de compliance em arquivos Markdown',
    test: (relPath) => {
        return relPath.toLowerCase().endsWith('.md');
    },
    aplicar: async (src, relPath, _ast, fullCaminho) => {
        if (!fullCaminho) {
            log.aviso(`detector-markdown: fullPath não fornecido para ${relPath}`);
            return [];
        }
        const cfg = config.detectorMarkdown;
        const whitelistMode = cfg?.whitelistMode === 'replace' || cfg?.whitelistMode === 'merge' ? cfg.whitelistMode : 'merge';
        const options = {
            checkProveniencia: cfg?.checkProveniencia ?? true,
            checkLicenses: cfg?.checkLicenses ?? true,
            checkReferences: cfg?.checkReferences ?? true,
            headerLines: typeof cfg?.headerLines === 'number' ? cfg.headerLines : 30,
            whitelist: mergeWhitelist(PADRAO_LISTA_BRANCA, cfg?.whitelist, whitelistMode)
        };
        try {
            const analise = await analisarArquivoMarkdown(fullCaminho, relPath, src, options);
            return converterParaOcorrencias(analise);
        }
        catch (error) {
            log.erro(`Erro ao analisar Markdown ${relPath}: ${error.message}`);
            return [];
        }
    }
};
export { analisarArquivoMarkdown };
//# sourceMappingURL=detector-markdown.js.map