package cn.axzo.workflow.core.converter.json;

import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNode;
import org.flowable.bpmn.model.BoundaryEvent;
import org.flowable.bpmn.model.EventDefinition;
import org.flowable.bpmn.model.FlowableListener;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.TimerEventDefinition;
import org.flowable.engine.delegate.BaseExecutionListener;

import java.util.ArrayList;
import java.util.List;

import static org.flowable.bpmn.model.ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION;

/**
 * 边界事件
 *
 * @author wangli
 * @since 2024-08-16 11:47
 */
public class BoundaryEventJsonConverter extends AbstractBpmnJsonConverter<BoundaryEvent> {
    @Override
    public BoundaryEvent convertJsonToElement(BpmnJsonNode node, Process process, String formKey) {
        BoundaryEvent boundaryEvent = new BoundaryEvent();
        boundaryEvent.setId(node.getId() + "_boundaryEvent");
        boundaryEvent.setCancelActivity(false);
        boundaryEvent.setAttachedToRefId(process.getId());

        // 设置执行监听
        setExecutionListeners(boundaryEvent);

        // 设置 TimerEventDefinition
        setTimerEventDefinition(boundaryEvent);
        return boundaryEvent;
    }

    private void setTimerEventDefinition(BoundaryEvent boundaryEvent) {
        List<EventDefinition> eventDefinitions = new ArrayList<>();
        TimerEventDefinition timerEventDefinition = new TimerEventDefinition();
        timerEventDefinition.setEndDate("${timerEndDate}");
        eventDefinitions.add(timerEventDefinition);
        boundaryEvent.setEventDefinitions(eventDefinitions);
    }

    private void setExecutionListeners(BoundaryEvent boundaryEvent) {
        List<FlowableListener> executionListeners = new ArrayList<>();
        // 设置执行监听
        FlowableListener executionListener = new FlowableListener();
        executionListener.setEvent(BaseExecutionListener.EVENTNAME_START);
        executionListener.setImplementationType(IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
        executionListener.setImplementation("${boundaryEventExecutionStartListener}");
        executionListeners.add(executionListener);

        boundaryEvent.setExecutionListeners(executionListeners);
    }
}
