import { criarOcorrencia } from '../../../types/index.js';
import { isOrgVerificada } from './org-verified.js';
const ACTIONS_DEPRECIADAS = new Map([
    ['actions/cache@v1', 'actions/cache@v3 ou superior'],
    ['actions/cache@v2', 'actions/cache@v3 ou superior'],
    ['actions/checkout@v1', 'actions/checkout@v3 ou superior'],
    ['actions/checkout@v2', 'actions/checkout@v3 ou superior'],
    ['actions/setup-node@v1', 'actions/setup-node@v3 ou superior'],
    ['actions/setup-node@v2', 'actions/setup-node@v3 ou superior'],
    ['actions/upload-artifact@v1', 'actions/upload-artifact@v3 ou superior'],
    ['actions/upload-artifact@v2', 'actions/upload-artifact@v3 ou superior'],
    ['actions/download-artifact@v1', 'actions/download-artifact@v3 ou superior'],
    ['actions/download-artifact@v2', 'actions/download-artifact@v3 ou superior'],
]);
export const detectorWorkflowCompliance = {
    nome: 'detector-workflow-compliance',
    categoria: 'workflows',
    descricao: 'Detecta problemas de compliance em GitHub Actions',
    test: (relPath) => /\.github\/workflows\/.*\.ya?ml$/i.test(relPath),
    aplicar: (src, relPath) => {
        if (!src)
            return [];
        const ocorrencias = [];
        const linhas = src.split('\n');
        linhas.forEach((linha, index) => {
            const numeroLinha = index + 1;
            const usesMatch = linha.match(/uses:\s*([^\s@]+)@([^\s]+)/);
            if (usesMatch) {
                const [, actionRef, version] = usesMatch;
                if (!isOrgVerificada(actionRef)) {
                    const isOrgAction = /^[a-zA-Z0-9-]+\/[a-zA-Z0-9-]+$/.test(actionRef);
                    if (isOrgAction) {
                        ocorrencias.push(criarOcorrencia({
                            tipo: 'workflow-action-nao-verificada',
                            nivel: 'aviso',
                            mensagem: `Action de fonte não verificada: ${actionRef}`,
                            relPath,
                            linha: numeroLinha,
                            sugestao: 'Prefira actions oficiais do GitHub ou de organizações verificadas'
                        }));
                    }
                }
                const actionKey = `${actionRef}@${version}`;
                if (ACTIONS_DEPRECIADAS.has(actionKey)) {
                    const recomendacao = ACTIONS_DEPRECIADAS.get(actionKey);
                    if (recomendacao) {
                        ocorrencias.push(criarOcorrencia({
                            tipo: 'workflow-action-depreciada',
                            nivel: 'aviso',
                            mensagem: `Action depreciada: ${actionKey}`,
                            relPath,
                            linha: numeroLinha,
                            sugestao: `Atualizar para ${recomendacao}`
                        }));
                    }
                }
            }
            if (/retention-days/.test(linha)) {
                const daysMatch = linha.match(/retention-days:\s*(\d+)/);
                if (daysMatch) {
                    const days = parseInt(daysMatch[1], 10);
                    if (days > 90) {
                        ocorrencias.push(criarOcorrencia({
                            tipo: 'workflow-retention-excessiva',
                            nivel: 'info',
                            mensagem: `Retenção de artifacts excessiva: ${days} dias`,
                            relPath,
                            linha: numeroLinha,
                            sugestao: 'Considere reduzir retention-days para 30 dias ou menos para economizar storage'
                        }));
                    }
                    else if (days === 0) {
                        ocorrencias.push(criarOcorrencia({
                            tipo: 'workflow-retention-infinita',
                            nivel: 'aviso',
                            mensagem: 'Retenção de artifacts infinita (0 dias)',
                            relPath,
                            linha: numeroLinha,
                            sugestao: 'Defina um período de retenção finito para evitar acúmulo de storage'
                        }));
                    }
                }
            }
        });
        if (!/retention-days/.test(src) && /upload-artifact/.test(src)) {
            ocorrencias.push(criarOcorrencia({
                tipo: 'workflow-sem-retention-policy',
                nivel: 'info',
                mensagem: 'Upload de artifacts sem política de retenção definida',
                relPath,
                linha: 1,
                sugestao: 'Adicionar retention-days para controlar armazenamento de artifacts'
            }));
        }
        return ocorrencias;
    }
};
export function detectarProblemasCompliance(workflow, _conteudo) {
    const problemas = [];
    const wf = workflow;
    if (!wf?.jobs)
        return problemas;
    for (const [, job] of Object.entries(wf.jobs)) {
        if (!job?.steps)
            continue;
        for (const step of job.steps) {
            if (!step.uses)
                continue;
            const usesMatch = step.uses.match(/([^\s@]+)@([^\s]+)/);
            if (!usesMatch)
                continue;
            const [, actionRef] = usesMatch;
            if (!isOrgVerificada(actionRef)) {
                const isOrgAction = /^[a-zA-Z0-9-]+\/[a-zA-Z0-9-]+$/.test(actionRef);
                if (isOrgAction) {
                    problemas.push({
                        tipo: 'action-nao-verificada',
                        descricao: `Action de fonte não verificada: ${actionRef}`,
                        severidade: 'media'
                    });
                }
            }
            if (step.with?.['retention-days'] !== undefined) {
                const days = Number(step.with['retention-days']);
                if (days > 90) {
                    problemas.push({
                        tipo: 'retention-excessiva',
                        descricao: `Retenção de artifacts excessiva: ${days} dias`,
                        severidade: 'baixa',
                        sugestao: 'Reduzir para 30 dias ou menos'
                    });
                }
            }
        }
    }
    return problemas;
}
//# sourceMappingURL=detector-workflow-compliance.js.map