package cn.axzo.workflow.core.engine.listener;

import cn.axzo.framework.jackson.utility.JSON;
import cn.axzo.workflow.core.listener.BpmnActivityEventListener;
import com.google.common.collect.ImmutableSet;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
import org.flowable.engine.delegate.event.FlowableActivityCancelledEvent;
import org.flowable.engine.delegate.event.FlowableActivityEvent;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_CANCELLED;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_COMPLETED;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_STARTED;

/**
 * 活动节点完成事件
 *
 * @author wangli
 * @since 2023/7/24 17:36
 */
@Slf4j
@Component
public class EngineActivityEventListener extends AbstractFlowableEngineEventListener {

    @Resource
    ObjectProvider<List<BpmnActivityEventListener>> activityListeners;

    public static final Set<FlowableEngineEventType> PROCESS_INSTANCE_EVENTS =
            ImmutableSet.<FlowableEngineEventType>builder()
                    .add(ACTIVITY_STARTED)
                    .add(ACTIVITY_COMPLETED)
                    .add(ACTIVITY_CANCELLED)
                    .build();

    public EngineActivityEventListener() {
        super(PROCESS_INSTANCE_EVENTS);
    }

    @Override
    protected void activityStarted(FlowableActivityEvent event) {
        log.info("activityStarted: activityId: {}  activityName: {}", event.getActivityId(), event.getActivityName());
        getOrderedListeners().forEach(i -> i.onStarted(event));
    }

    @Override
    protected void activityCompleted(FlowableActivityEvent event) {
        log.info("activityCompleted: activityId: {}  activityName: {}", event.getActivityId(), event.getActivityName());
        getOrderedListeners().forEach(i -> i.onCompleted(event));
    }

    @Override
    protected void activityCancelled(FlowableActivityCancelledEvent event) {
        log.info("activityCancelled: activityId: {}  activityName: {}", event.getActivityId(), event.getActivityName());
        getOrderedListeners().forEach(i -> i.onCancelled(event));
    }


    private List<BpmnActivityEventListener> getOrderedListeners() {
        List<BpmnActivityEventListener> orderListeners = new ArrayList<>();
        activityListeners.ifAvailable(orderListeners::addAll);
        if (log.isDebugEnabled()) {
            log.debug("Order Lists: {}", JSON.toJSONString(orderListeners));
        }
        return orderListeners;
    }
}
