package org.camunda.bpm.extension.process_test_coverage.junit.rules;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import org.camunda.bpm.engine.impl.bpmn.parser.BpmnParseListener;
import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.camunda.bpm.engine.impl.event.EventHandler;
import org.camunda.bpm.engine.impl.history.handler.HistoryEventHandler;
import org.camunda.bpm.extension.process_test_coverage.listeners.CompensationEventCoverageHandler;
import org.camunda.bpm.extension.process_test_coverage.listeners.FlowNodeHistoryEventHandler;
import org.camunda.bpm.extension.process_test_coverage.listeners.PathCoverageParseListener;

/**
 * Helper methods to configure the process coverage extensions on a given ProcessEngineConfigurationImpl
 *
 * @author z0rbas / lldata
 *
 */
public class ProcessCoverageConfigurator {

    public static void initializeProcessCoverageExtensions(ProcessEngineConfigurationImpl configuration) {
        initializeFlowNodeHandler(configuration);
        initializePathCoverageParseListener(configuration);
        initializeCompensationEventHandler(configuration);
    }

    public static void initializeProcessCoverageExtensionsSpringBoot(ProcessEngineConfigurationImpl configuration) {
        initializeFlowNodeHandlerSpringBoot(configuration);
        initializePathCoverageParseListener(configuration);
        initializeCompensationEventHandler(configuration);
    }

    private static void initializePathCoverageParseListener(ProcessEngineConfigurationImpl configuration) {
        List<BpmnParseListener> bpmnParseListeners = configuration.getCustomPostBPMNParseListeners();
        if (bpmnParseListeners == null) {
            bpmnParseListeners = new LinkedList<BpmnParseListener>();
            configuration.setCustomPostBPMNParseListeners(bpmnParseListeners);
        }

        bpmnParseListeners.add(new PathCoverageParseListener());
    }

    private static void initializeFlowNodeHandler(ProcessEngineConfigurationImpl configuration) {
        final FlowNodeHistoryEventHandler historyEventHandler = new FlowNodeHistoryEventHandler();
        configuration.setHistoryEventHandler(historyEventHandler);

    }

    private static void initializeFlowNodeHandlerSpringBoot(ProcessEngineConfigurationImpl configuration) {
        final FlowNodeHistoryEventHandler historyEventHandler = new FlowNodeHistoryEventHandler();
        configuration.setCustomHistoryEventHandlers(Arrays.asList((HistoryEventHandler)historyEventHandler));
        configuration.setEnableDefaultDbHistoryEventHandler(false);
    }

    private static void initializeCompensationEventHandler(ProcessEngineConfigurationImpl configuration) {
        if (configuration.getCustomEventHandlers() == null) {
            configuration.setCustomEventHandlers(new LinkedList<EventHandler>());
        }

        configuration.getCustomEventHandlers().add(new CompensationEventCoverageHandler());
    }

}

@@ -63,16 +63,101 @@
 rules;%0A%0A
+import java.lang.reflect.InvocationTargetException;%0Aimport java.lang.reflect.Method;%0A
 import j
@@ -2527,52 +2527,298 @@
     
-configuration.setCustomHistoryEventHandlers(
+try %7B%0A          Method setCustomHistoryEventHandlers = ProcessEngineConfigurationImpl.class%0A              .getDeclaredMethod(%22setCustomHistoryEventHandlers%22, List.class);%0A          if (setCustomHistoryEventHandlers != null) %7B%0A            setCustomHistoryEventHandlers.invoke(configuration, 
 Arra
@@ -2848,16 +2848,17 @@
 Handler)
+ 
 historyE
@@ -2884,67 +2884,589 @@
     
-configuration.setEnableDefaultDbHistoryEventHandler(false);
+    Method setEnableDefaultDbHistoryEventHandler = ProcessEngineConfigurationImpl.class%0A                .getDeclaredMethod(%22setEnableDefaultDbHistoryEventHandler%22, boolean.class);%0A            if (setEnableDefaultDbHistoryEventHandler != null) %7B%0A              setEnableDefaultDbHistoryEventHandler.invoke(configuration, false);%0A            %7D%0A          %7D%0A        %7D catch (NoSuchMethodException %7C IllegalAccessException %7C IllegalArgumentException %7C InvocationTargetException e) %7B%0A          // expected for Camunda %3C 7.13.0%0A          initializeFlowNodeHandler(configuration);%0A        %7D
 %0A   

Support older Camunda versions by using reflection