package com.cmvr.test.flow.runtime.interceptor;

import cn.hutool.core.util.StrUtil;
import com.cmvr.test.enums.NodeTypeEnum;
import com.cmvr.test.flow.context.TaskContext;
import com.cmvr.test.flow.context.TaskInstHolder;
import com.cmvr.test.flow.runtime.event.FlowExecutionEventPublisher;
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteMessage;
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.function.Function;

@Slf4j
@Component
@Order(4)
public class FlowLoggingInterceptor extends AbstractFlowMsgPreInterceptor {

    private final TaskInstHolder taskInstHolder;

    public FlowLoggingInterceptor(FlowExecutionEventPublisher eventPublisher, TaskInstHolder taskInstHolder) {
        super(eventPublisher);
        this.taskInstHolder = taskInstHolder;
    }

    @Override
    public TaskNodeExecuteResult doIntercept(TaskNodeExecuteMessage message,
                                           Function<TaskNodeExecuteMessage, TaskNodeExecuteResult> next) {
        long start = System.currentTimeMillis();
        log.info("[ {} ]节点开始执行, 参数[ {} ], 循环次数[ {} ]", message.getAction(), message.getInputParams(), message.getLoopNum());

        // todo 判断一下是否为LOOP重入
        if (!(message.getNodeType().equalsIgnoreCase(NodeTypeEnum.LOOP.getCode()) && message.getLoopNum() > 0)) {
            taskInstHolder.markRunning(message.getInstId(), message.getTaskId(), message.getItemId(), message.getNodeId(),
                    message.getNodeType(), message.getAction().getOperate(), message.getAction().getAction(),
                    message.getInputParams().toJSONString(), message.getIterations());
        }

        TaskNodeExecuteResult result = next.apply(message);

        // 节点执行返回拦截  判断此时是否被终止或暂停
        TaskContext context = taskInstHolder.getContext(message.getInstId());
        if (context == null || context.isPaused()) {
            // 确认是否已终止或已暂停
            log.info("当前流程已经暂停/终止");
            return null;
        }

        taskInstHolder.markSuccess(message.getInstId(), message.getItemId(), message.getNodeId(), message.getPendingItemCount(), message.getNodeType(),
                result.getOutputParams().toJSONString(), StrUtil.format("[{}] 执行成功", message.getAction()), message.getIterations());

        long end = System.currentTimeMillis();
        log.info("[ {} ]节点执行结束, 参数[ {} ], 循环次数[ {} ], 耗时[ {} ]", message.getAction(), message.getInputParams(), message.getLoopNum(), end - start);
        return result;
    }
}
