package cn.axzo.workflow.starter.mq.broadcast.consumer;

import cn.axzo.framework.rocketmq.Event;
import cn.axzo.framework.rocketmq.EventConsumer;
import cn.axzo.workflow.common.enums.ProcessTaskEventEnum;
import cn.axzo.workflow.common.model.response.mq.ProcessTaskDTO;
import cn.axzo.workflow.starter.handler.ProcessTaskEventHandler;
import cn.axzo.workflow.starter.handler.execute.ListenerExecutor;
import cn.axzo.workflow.starter.handler.filter.ProcessTaskEventFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectProvider;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * @author wangli
 * @since 2024/5/21 15:51
 */
public class InnerTaskEventListener extends AbstractWorkflowListener<ProcessTaskEventHandler, ProcessTaskEventFilter, ProcessTaskDTO> {
    private final Logger log = LoggerFactory.getLogger(InnerTaskEventListener.class);

    public final static Supplier<List<Event.EventCode>> SUPPORTED_EVENT_CODES_SUPPLIER = () ->
            Arrays.stream(ProcessTaskEventEnum.values()).map(ProcessTaskEventEnum::getEventCode)
                    .collect(Collectors.toList());

    public InnerTaskEventListener(ListenerExecutor executor, ObjectProvider<List<ProcessTaskEventHandler>> provider, ObjectProvider<List<ProcessTaskEventFilter>> filterProvider) {
        super(executor, provider, filterProvider);
    }

    @Override
    protected ProcessTaskDTO convert(Event event) {
        return event.normalizedData(ProcessTaskDTO.class);
    }

    @Override
    public void onEvent(ProcessTaskDTO taskDTO, EventConsumer.Context context) {
        ProcessTaskEventEnum type = taskDTO.getType();
        for (ProcessTaskEventHandler taskListener : businessListeners) {
            Consumer<ProcessTaskDTO> consumer = null;
            switch (type) {
                case PROCESS_TASK_CREATED:
                    consumer = taskListener::onCreated;
                    break;
                case PROCESS_TASK_COMPLETED:
                    consumer = taskListener::onCompleted;
                    break;
                case PROCESS_TASK_ASSIGNED:
                    consumer = taskListener::onAssigned;
                    break;
                case PROCESS_TASK_DELETED:
                    consumer = taskListener::onDeleted;
                    break;
                default:
                    log.warn("unknown task event type: {}", type);
            }
            getListenerExecutor().execute(consumer, taskDTO);
        }

    }

    @Override
    protected List<Event.EventCode> getSupportEventCodes() {
        return SUPPORTED_EVENT_CODES_SUPPLIER.get();
    }

}
