import { messages } from '../../../core/messages/index.js';
import { splitLines } from '../../../shared/helpers/index.js';
import { parseDocument } from 'yaml';
import { criarOcorrencia } from '../../../types/index.js';
const BRANCHES_PROTEGIDOS = ['main', 'master', 'production', 'release', 'prod'];
const DANGEROUS_ACTIONS = ['actions/checkout', 'peter-evans/create-or-update-comment', 'peter-evans/create-pull-request', 'marocchino/sticky-pull-request', 'softprops/action-gh-release', 'ncipollo/release-action', 'docker/build-push-action', 'docker/login-action', 'docker/push-action', 'aws-actions/configure-aws-credentials', 'google-github-actions/auth', 'azure/login', 'hashicorp/vault-action'];
export const detectorWorkflowTriggerInseguro = {
    nome: 'detector-workflow-trigger-inseguro',
    categoria: 'workflows',
    descricao: 'Detecta triggers de workflow potencialmente inseguros',
    test: (relPath) => /\.github\/workflows\/.*\.ya?ml$/i.test(relPath),
    aplicar: (src, relPath) => {
        if (!src)
            return [];
        const ocorrencias = [];
        try {
            const doc = parseDocument(src);
            const workflow = doc.toJS();
            if (!workflow || typeof workflow !== 'object')
                return ocorrencias;
            const onConfig = workflow.on;
            if (!onConfig || typeof onConfig !== 'object') {
                ocorrencias.push(criarOcorrencia({
                    tipo: 'trigger-ausente',
                    nivel: 'info',
                    mensagem: messages.AnalistaGithubActionsMensagens.workflowWithoutTrigger,
                    relPath,
                    linha: 1,
                    sugestao: messages.AnalistaGithubActionsMensagens.workflowWithoutTriggerSugestao
                }));
                return ocorrencias;
            }
            if (onConfig.push) {
                const pushConf = onConfig.push;
                if (pushConf.tags && !pushConf.branches && !pushConf['branches-ignore']) {
                }
                else {
                    const branches = typeof pushConf === 'object' && pushConf?.branches ? Array.isArray(pushConf.branches) ? pushConf.branches : [pushConf.branches] : typeof pushConf === 'object' && pushConf?.branches_ignore ? Array.isArray(pushConf.branches_ignore) ? pushConf.branches_ignore : [pushConf.branches_ignore] : undefined;
                    if (typeof pushConf === 'object' && !pushConf.branches && !pushConf.branches_ignore && !pushConf.tags || Array.isArray(pushConf) || typeof pushConf === 'string') {
                        ocorrencias.push(criarOcorrencia({
                            tipo: 'trigger-push-sem-filtro',
                            nivel: 'aviso',
                            mensagem: 'Trigger push sem filtro de branches definido',
                            relPath,
                            linha: 1,
                            sugestao: 'Defina branches específicos em on.push.branches para limitar onde o workflow é executado'
                        }));
                    }
                    if (branches) {
                        const hasPathsFilter = !!(pushConf.paths || pushConf.paths_ignore || pushConf['paths-ignore'] || pushConf.pathsIgnore);
                        if (!hasPathsFilter) {
                            for (const branch of branches) {
                                if (typeof branch === 'string' && BRANCHES_PROTEGIDOS.some(caminho => branch.toLowerCase() === caminho.toLowerCase() || new RegExp(`^${caminho.replace('/', '\\/')}`).test(branch))) {
                                    ocorrencias.push(criarOcorrencia({
                                        tipo: 'trigger-push-branch-protegido',
                                        nivel: 'aviso',
                                        mensagem: `Trigger push configurado para branch protegido "${branch}" sem filtro de paths`,
                                        relPath,
                                        linha: 1,
                                        sugestao: 'Adicione filtros de paths (on.push.paths) para limitar quando o workflow é executado'
                                    }));
                                }
                            }
                        }
                    }
                }
            }
            if (onConfig.pull_request) {
                if (onConfig.pull_request_target) {
                    ocorrencias.push(criarOcorrencia({
                        tipo: 'trigger-pull-request-target',
                        nivel: 'erro',
                        mensagem: messages.AnalistaGithubActionsMensagens.pullRequestTargetGrantsWritePermissions,
                        relPath,
                        linha: 1,
                        sugestao: messages.AnalistaGithubActionsMensagens.pullRequestTargetGrantsWritePermissionsSugestao
                    }));
                }
            }
            if (onConfig.workflow_dispatch) {
                const dispatchConf = onConfig.workflow_dispatch;
                if (typeof dispatchConf === 'object' && dispatchConf.inputs) {
                    const inputs = dispatchConf.inputs;
                    for (const [_inputName, inputConfig] of Object.entries(inputs)) {
                        const inputConf = inputConfig;
                        if (inputConf && !inputConf.required) {
                        }
                    }
                }
                if (typeof dispatchConf !== 'object' || !dispatchConf.inputs) {
                    ocorrencias.push(criarOcorrencia({
                        tipo: 'trigger-workflow-dispatch-sem-inputs',
                        nivel: 'info',
                        mensagem: messages.AnalistaGithubActionsMensagens.workflowDispatchWithoutInputs,
                        relPath,
                        linha: 1,
                        sugestao: messages.AnalistaGithubActionsMensagens.workflowDispatchWithoutInputsSugestao
                    }));
                }
            }
            if (onConfig.schedule) {
                const pushConf = onConfig.push;
                const targetBranches = typeof pushConf === 'object' && pushConf?.branches ? Array.isArray(pushConf.branches) ? pushConf.branches : [pushConf.branches] : undefined;
                if (targetBranches) {
                    for (const branch of targetBranches) {
                        if (typeof branch === 'string' && branch.toLowerCase() === 'production') {
                            ocorrencias.push(criarOcorrencia({
                                tipo: 'trigger-schedule-branch-sensivel',
                                nivel: 'aviso',
                                mensagem: 'Workflow com schedule direcionado para branch "production"',
                                relPath,
                                linha: 1,
                                sugestao: 'Considere usar branches de staging para execuções agendadas'
                            }));
                        }
                    }
                }
            }
            const yamlRaw = src;
            if (/on:\s*\n\s*push:\s*\n\s*branches:\s*\n\s*-\s+'\*\*'/m.test(yamlRaw) || /on:\s*\n\s*push:\s*\n\s*branches:\s*\n\s*-\s+"\*\*"/m.test(yamlRaw)) {
                ocorrencias.push(criarOcorrencia({
                    tipo: 'trigger-wildcard-amplo',
                    nivel: 'info',
                    mensagem: 'Trigger push com wildcard "**" em branches (captura todos os branches)',
                    relPath,
                    linha: 1,
                    sugestao: 'Use padrões mais específicos para limitar os branches monitorados'
                }));
            }
            if (onConfig.push && !onConfig.pull_request) {
                const isPushToTags = onConfig.push.tags && !onConfig.push.branches && !onConfig.push['branches-ignore'];
                if (!isPushToTags) {
                    const linhas = splitLines(src);
                    const hasDangerousAction = linhas.some(linha => {
                        const usesMatch = linha.match(/uses:\s*(.+)/);
                        return usesMatch && DANGEROUS_ACTIONS.some(arquivo => linha.includes(arquivo));
                    });
                    const isPushToAllBranches = !onConfig.push.branches && !onConfig.push['branches-ignore'];
                    if (isPushToAllBranches && hasDangerousAction) {
                        ocorrencias.push(criarOcorrencia({
                            tipo: 'trigger-push-ampla-com-actions-perigosas',
                            nivel: 'aviso',
                            mensagem: 'Push sem restrição de branches executa actions que modificam estado do repositório',
                            relPath,
                            linha: 1,
                            sugestao: 'Considere restringir push branches ou adicionar proteções (environment protection rules, approvals)'
                        }));
                    }
                }
            }
        }
        catch {
            if (src.includes('pull_request_target:')) {
                ocorrencias.push(criarOcorrencia({
                    tipo: 'trigger-pull-request-target',
                    nivel: 'erro',
                    mensagem: messages.AnalistaGithubActionsMensagens.pullRequestTargetGrantsWritePermissions,
                    relPath,
                    linha: 1,
                    sugestao: messages.AnalistaGithubActionsMensagens.pullRequestTargetExecutesForkCodeSugestao
                }));
            }
            if (/on:\s*push:\s*$/m.test(src) || /on:\s*\n\s*push:\s*true\s*$/m.test(src)) {
                ocorrencias.push(criarOcorrencia({
                    tipo: 'trigger-push-sem-filtro',
                    nivel: 'aviso',
                    mensagem: 'Trigger push sem filtro de branches definido',
                    relPath,
                    linha: 1,
                    sugestao: 'Defina branches específicos em on.push.branches'
                }));
            }
        }
        return ocorrencias;
    }
};
//# sourceMappingURL=detector-workflow-trigger-unsafe.js.map