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

import com.alibaba.fastjson2.JSONObject;
import com.cmvr.test.enums.RunModeEnum;
import com.cmvr.test.flow.context.TaskContext;
import com.cmvr.test.flow.context.TaskInstHolder;
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteMessage;
import com.cmvr.test.model.dto.TeQueryTaskDetailDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.CountDownLatch;

@Slf4j
@Component
@RequiredArgsConstructor
public class FlowTaskEngine {

    private final TaskInstHolder taskInstHolder;

    private final FlowItemExecutor flowTaskExecutor;

    public void run(String instId, String taskId, String terminalId,
                    RunModeEnum runMode, List<TeQueryTaskDetailDTO> items) {
        TaskContext context = taskInstHolder.getContext(instId);
        context.setRunMode(runMode);
        JSONObject runParams = context.getRunParams();

        int totalItemCount = items.size();

        for (int i = 0; i < totalItemCount; i++) {
            TeQueryTaskDetailDTO item = items.get(i);
            // 等待当前 item 完成后再执行下一个
            CountDownLatch latch = new CountDownLatch(1);
            String itemId = item.getDetectItemId();
            context.setItemId(itemId);

            TaskNodeExecuteMessage message = new TaskNodeExecuteMessage();
            message.setInstId(instId);
            message.setTaskId(taskId);
            message.setTerminalId(terminalId);
            message.setItemId(itemId);
            if (runMode.equals(RunModeEnum.VI_PROJECT)) {
                message.setLoopDetail(item.getSchemeInfo());
            }

            int pendingItemCount = totalItemCount - i - 1;
            message.setPendingItemCount(pendingItemCount);

            JSONObject jsonObject = runParams.getJSONObject(itemId);
            if (!runMode.equals(RunModeEnum.TRIAL)) {
                context.setRunParams(jsonObject);
            }
            flowTaskExecutor.executeGraph(message, item, latch::countDown);
            try {
                latch.await(); // 等待该检测项的子流程全部完成
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.error("检测项执行被中断：itemId={}", itemId, e);
                break;
            }
        }
    }
}
