package com.ruoyi.platform.service.impl;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.platform.domain.DatasetTempStorage;
import com.ruoyi.platform.domain.Experiment;
import com.ruoyi.platform.domain.ExperimentIns;
import com.ruoyi.platform.domain.ModelDependency1;
import com.ruoyi.platform.mapper.DatasetTempStorageDao;
import com.ruoyi.platform.mapper.ExperimentDao;
import com.ruoyi.platform.mapper.ExperimentInsDao;
import com.ruoyi.platform.mapper.ModelDependency1Dao;
import com.ruoyi.platform.service.ExperimentInsService;
import com.ruoyi.platform.service.ResourceOccupyService;
import com.ruoyi.platform.utils.*;
import com.ruoyi.platform.vo.LogRequestVo;
import com.ruoyi.platform.vo.PodLogVo;
import com.ruoyi.system.api.constant.Constant;
import com.ruoyi.system.api.model.LoginUser;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.*;

/**
 * (ExperimentIns)表服务实现类
 *
 * @author makejava
 * @since 2023-11-07 15:08:23
 */
@Service("experimentInsService")
public class ExperimentInsServiceImpl implements ExperimentInsService {
    private static final Logger logger = LoggerFactory.getLogger(ExperimentInsServiceImpl.class);

    @Resource
    private ExperimentInsDao experimentInsDao;
    @Resource
    private ExperimentDao experimentDao;
    @Value("${argo.url}")
    private String argoUrl;
    @Value("${argo.workflowStatus}")
    private String argoWorkflowStatus;
    @Value("${argo.workflowTermination}")
    private String argoWorkflowTermination;
    @Value("${argo.workflowLog}")
    private String argoWorkflowLog;
    @Value("${argo.workflowRealTimeLog}")
    private String argoWorkflowRealTimeLog;
    @Value("${argo.workflowPodLog}")
    private String argoWorkflowPodLog;
    @Value("${argo.ins.logsLines}")
    private int logsLines;
    @Resource
    private K8sClientUtil k8sClientUtil;
    @Resource
    private ModelsServiceImpl modelsService;
    @Resource
    private NewDatasetServiceImpl newDatasetService;

    @Resource
    private ModelDependency1Dao modelDependency1Dao;

    @Resource
    private DatasetTempStorageDao datasetTempStorageDao;

    @Resource
    private ResourceOccupyService resourceOccupyService;

    private final MinioUtil minioUtil;

    public ExperimentInsServiceImpl(MinioUtil minioUtil) {
        this.minioUtil = minioUtil;
    }


    public enum ExperimentInsStatus {
        Running,
        Succeeded,
        Pending,
        Failed,
        Terminated
    }


    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public ExperimentIns queryById(Integer id) throws IOException {
        ExperimentIns experimentIns = this.experimentInsDao.queryById(id);

        //已经迁移至定时任务进行更新操作
//        if (experimentIns != null && (StringUtils.isEmpty(experimentIns.getStatus())) || !isTerminatedState(experimentIns)) {
//            experimentIns = this.queryStatusFromArgo(experimentIns);
//            //只有当新状态是终止态时才更新数据库
//            if (isTerminatedState(experimentIns)) {
//                //同时更新各个节点
//                this.update(experimentIns);
//            }
//        }
        return experimentIns;
    }

    /**
     * 根据实验ID查找所有具有相同ID的实例，并将它们添加到实验列表中
     *
     * @param experimentId 实验ID
     * @return 实验列表
     */
    @Override
    public List<ExperimentIns> getByExperimentId(Integer experimentId) {

        //代码全部迁移至定时任务
        //搞个标记，当状态改变才去改表
//        boolean flag = false;
//        List<ExperimentIns> result = new ArrayList<ExperimentIns>();
//        if (experimentInsList!=null && experimentInsList.size()>0) {
//            for (ExperimentIns experimentIns : experimentInsList) {
//                //当原本状态为null或非终止态时才调用argo接口
//                if (experimentIns != null && (StringUtils.isEmpty(experimentIns.getStatus())) || !isTerminatedState(experimentIns)) {
//                    experimentIns = this.queryStatusFromArgo(experimentIns);
//                    if (!flag){
//                        flag = true;
//                    }
//                    //只有当新状态是终止态时才更新数据库
//                    if (isTerminatedState(experimentIns)) {
//                        //同时更新各个节点
//                        this.update(experimentIns);
//                    }
//                }
//
//                //新增查询tensorBoard容器状态
//                result.add(experimentIns);
//            }
//        }
//        if (flag) {
//            List<String> statusList = new ArrayList<String>();
//            // 更新实验状态列表
//            for (int i=0;i<result.size();i++){
//                statusList.add(result.get(i).getStatus());
//            }
//            Experiment experiment = experimentDao.queryById(experimentId);
//            experiment.setStatusList(statusList.toString().substring(1, statusList.toString().length()-1));
//            experimentDao.update(experiment);
//        }

        return experimentInsDao.getByExperimentId(experimentId);

    }

    /**
     * 分页查询
     *
     * @param experimentIns 筛选条件
     * @param pageRequest   分页对象
     * @return 查询结果
     */
    @Override
    public Page<ExperimentIns> queryByPage(ExperimentIns experimentIns, PageRequest pageRequest) throws IOException {
        long total = this.experimentInsDao.count(experimentIns);
        List<ExperimentIns> experimentInsList = this.experimentInsDao.queryAllByLimit(experimentIns, pageRequest);
        return new PageImpl<>(experimentInsList, pageRequest, total);
    }

    /**
     * 新增数据
     *
     * @param experimentIns 实例对象
     * @return 实例对象
     */
    @Override
    public ExperimentIns insert(ExperimentIns experimentIns) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        experimentIns.setCreateBy(loginUser.getUsername());
        experimentIns.setUpdateBy(loginUser.getUsername());
        experimentIns.setUpdateTime(new Date());
        experimentIns.setCreateTime(new Date());
        experimentIns.setState(1);
        this.experimentInsDao.insert(experimentIns);
        return experimentIns;
    }


    /**
     * 修改数据
     *
     * @param experimentIns 实例对象
     * @return 实例对象
     */
    @Override
    public ExperimentIns update(ExperimentIns experimentIns) throws IOException {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        experimentIns.setUpdateBy(loginUser.getUsername());
        experimentIns.setUpdateTime(new Date());
        experimentIns = queryStatusFromArgo(experimentIns);
        this.experimentInsDao.update(experimentIns);
        updateExperimentStatus(experimentIns.getExperimentId());
        if (Constant.Failed.equals(experimentIns.getStatus()) || Constant.Succeeded.equals(experimentIns.getStatus())) {
            if (StringUtils.isNotEmpty(experimentIns.getNodesStatus())) {
                Map<String, Object> nodesStatusMap = JsonUtils.jsonToMap(experimentIns.getNodesStatus());
                for (String key : nodesStatusMap.keySet()) {
                    Map<String, Object> value = (Map<String, Object>) nodesStatusMap.get(key);
                    String startedAt = (String) value.get("startedAt");
                    Instant instant = Instant.parse(startedAt);
                    Date startTime = Date.from(instant);
                    String finishedAt = (String) value.get("finishedAt");
                    if (StringUtils.isNotEmpty(finishedAt)) {
                        resourceOccupyService.endDeduce(Constant.TaskType_Workflow, null, Long.valueOf(experimentIns.getId()), key, startTime);
                    }
                }
            }
        }
        return experimentIns;
    }

    @Override
    @Transactional
    public String removeById(Integer id) {
        ExperimentIns experimentIns = experimentInsDao.queryById(id);
        if (experimentIns == null) {
            throw new RuntimeException("实验实例不存在");
        }

        //判断权限，只有admin和创建者本身可以删除该实验实例
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String username = loginUser.getUsername();
        String createdBy = experimentIns.getCreateBy();
        if (!(StringUtils.equals(username, "admin") || StringUtils.equals(username, createdBy))) {
            throw new RuntimeException("无权限删除该实验实例");
        }

        if (StringUtils.isEmpty(experimentIns.getStatus())) {
            experimentIns = queryStatusFromArgo(experimentIns);
        }
        if (StringUtils.equals(experimentIns.getStatus(), Constant.Running)) {
            throw new RuntimeException("实验实例正在运行，不可删除");
        }
        experimentIns.setState(Constant.State_invalid);
        int update = this.experimentInsDao.update(experimentIns);
        if (update > 0) {
            resourceOccupyService.deleteTaskState(Constant.TaskType_Workflow, Long.valueOf(experimentIns.getExperimentId()), Long.valueOf(id));
            updateExperimentStatus(experimentIns.getExperimentId());
            return "删除成功";
        } else {
            return "删除失败";
        }
    }

    @Override
    public String batchDelete(List<Integer> ids) {
        for (Integer id : ids) {
            String result = removeById(id);
            if (!"删除成功".equals(result)) {
                return result;
            }
        }
        return "删除成功";
    }


    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        return this.experimentInsDao.deleteById(id) > 0;
    }

    @Override
    public List<ExperimentIns> queryByExperimentId(Integer id) {
        return experimentInsDao.queryByExperimentId(id);
    }

    @Override
    public ExperimentIns queryStatusFromArgo(ExperimentIns ins) {
        String namespace = ins.getArgoInsNs();
        String name = ins.getArgoInsName();
        Integer id = ins.getId();
        // 创建请求数据map
        Map<String, Object> requestData = new HashMap<>();
        requestData.put("namespace", namespace);
        requestData.put("name", name);
        // 创建发送数据map，将请求数据作为"data"键的值
        Map<String, Object> res = new HashMap<>();
        res.put("data", requestData);

        try {
            // 发送POST请求到Argo工作流状态查询接口，并将请求数据转换为JSON
            String req = HttpUtils.sendPost(argoUrl + argoWorkflowStatus, null, JsonUtils.mapToJson(res));
            // 检查响应是否为空或无内容
            if (req == null || StringUtils.isEmpty(req)) {
                throw new RuntimeException("工作流状态响应为空");
            }

            // 将响应的JSON字符串转换为Map对象
            Map<String, Object> runResMap = JsonUtils.jsonToMap(req);
            // 从响应Map中获取"data"部分
            Map<String, Object> data = (Map<String, Object>) runResMap.get("data");
            if (data == null || data.isEmpty()) {
                throw new RuntimeException("工作流数据为空");
            }
            // 从"data"中获取"status"部分，并返回"phase"的值
            Map<String, Object> status = (Map<String, Object>) data.get("status");
            if (status == null || status.isEmpty()) {
                throw new RuntimeException("工作流状态为空");
            }

            //解析流水线结束时间
            String finishedAtString = (String) status.get("finishedAt");
            if (finishedAtString != null && !finishedAtString.isEmpty()) {
                Date finishTime = DateUtils.convertUTCtoShanghaiDate(finishedAtString);
                ins.setFinishTime(finishTime);
            }

            // 解析nodes字段,提取节点状态并转换为JSON字符串
            Map<String, Object> nodes = (Map<String, Object>) status.get("nodes");
            Map<String, Object> modifiedNodes = new LinkedHashMap<>();
            if (nodes != null) {
                for (Map.Entry<String, Object> nodeEntry : nodes.entrySet()) {
                    Map<String, Object> nodeDetails = (Map<String, Object>) nodeEntry.getValue();
                    String templateName = (String) nodeDetails.get("displayName");
                    modifiedNodes.put(templateName, nodeDetails);
                }
            }

            String nodeStatusJson = JsonUtils.mapToJson(modifiedNodes);
            ins.setNodesStatus(nodeStatusJson);

            //终止态为终止不改
            if (!StringUtils.equals(ins.getStatus(), Constant.Terminated)) {
                ins.setStatus(StringUtils.isNotEmpty((String) status.get("phase")) ? (String) status.get("phase") : Constant.Pending);
            }
            if (StringUtils.equals(ins.getStatus(), Constant.Error)) {
                ins.setStatus(Constant.Failed);
            }
            return ins;
        } catch (Exception e) {
            throw new RuntimeException("查询状态失败: " + e.getMessage(), e);

        }

    }

    /**
     * 终止已经创建的实验实例
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean terminateExperimentIns(Integer id) throws Exception {
        //先查出实验记录
        ExperimentIns experimentIns = this.experimentInsDao.queryById(id);
        if (experimentIns == null) {
            throw new IllegalStateException("实验实例未查询到，id: " + id);
        }

        String currentStatus = experimentIns.getStatus();
        String name = experimentIns.getArgoInsName();
        String namespace = experimentIns.getArgoInsNs();
        // 获取当前状态，如果为空，则从Argo查询
        if (StringUtils.isEmpty(currentStatus)) {
            currentStatus = queryStatusFromArgo(experimentIns).getStatus();
        }

        // 只有状态是"Running"时才能终止实例
        if (!currentStatus.equalsIgnoreCase(Constant.Running)) {
            throw new Exception("终止错误，只有运行状态的实例才能终止"); // 如果不是"Running"状态，则不执行终止操作
        }

        // 创建请求数据map
        Map<String, Object> requestData = new HashMap<>();
        requestData.put("namespace", namespace);
        requestData.put("name", name);
        // 创建发送数据map，将请求数据作为"data"键的值
        Map<String, Object> res = new HashMap<>();
        res.put("data", requestData);

        try {
            // 发送POST请求到Argo工作流状态查询接口，并将请求数据转换为JSON
            String req = HttpUtils.sendPost(argoUrl + argoWorkflowTermination, null, JsonUtils.mapToJson(res));
            // 检查响应是否为空或无内容
            if (StringUtils.isEmpty(req)) {
                throw new RuntimeException("终止响应内容为空");

            }
            // 将响应的JSON字符串转换为Map对象
            Map<String, Object> runResMap = JsonUtils.jsonToMap(req);
            // 从响应Map中直接获取"errCode"的值
            Integer errCode = (Integer) runResMap.get("errCode");
            if (errCode != null && errCode == 0) {
                //更新experimentIns,确保状态更新被保存到数据库
                ExperimentIns ins = queryStatusFromArgo(experimentIns);
                String nodesStatus = ins.getNodesStatus();
                Map<String, Object> nodeMap = JsonUtils.jsonToMap(nodesStatus);

                // 遍历 map
                for (Map.Entry<String, Object> entry : nodeMap.entrySet()) {
                    // 获取每个 Map 中的值并强制转换为 Map
                    Map<String, Object> innerMap = (Map<String, Object>) entry.getValue();

                    // 检查 phase 的值
                    if (innerMap.containsKey("phase")) {
                        String phaseValue = (String) innerMap.get("phase");

                        // 如果值不等于 Succeeded，则赋值为 Failed
                        if (!StringUtils.equals(Constant.Succeeded, phaseValue)) {
                            innerMap.put("phase", Constant.Failed);
                            Calendar calendar = Calendar.getInstance();
                            calendar.add(Calendar.HOUR_OF_DAY, -8);
                            innerMap.put("finishedAt", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(calendar.getTime()));
                        }
                    }
                }
                ins.setNodesStatus(JsonUtils.mapToJson(nodeMap));
                ins.setStatus(Constant.Terminated);
                ins.setFinishTime(new Date());
                ins.setUpdateTime(new Date());
                this.experimentInsDao.update(ins);

                //删除数据集模型导出版本
                deleteExportVersion(experimentIns);
                //修改实验状态
                updateExperimentStatus(experimentIns.getExperimentId());

                // 结束扣除积分
                resourceOccupyService.endDeduce(Constant.TaskType_Workflow, null, Long.valueOf(experimentIns.getId()), null, null);
                return true;
            } else {
                throw new Exception("终止错误");
            }
        } catch (Exception e) {
            throw new RuntimeException("终止实例错误: " + e.getMessage(), e);
        }

    }

    void deleteExportVersion(ExperimentIns experimentIns) {
        try {
            LoginUser loginUser = SecurityUtils.getLoginUser();
            String ci4sUsername = loginUser.getUsername();

            String nodesResult = experimentIns.getNodesResult();

            if (StringUtils.isNotEmpty(nodesResult)) {
                Map<String, Object> nodesResultMap = JsonUtils.jsonToMap(nodesResult);
                Map<String, Object> paramOutput = (Map<String, Object>) nodesResultMap.get("param_output");

                for (String key : paramOutput.keySet()) {
                    //删除导出模型版本
                    if (key.contains("model-export")) {
                        HashMap queryMap = new HashMap<String, Integer>();
                        queryMap.put("insId", experimentIns.getId());
                        ModelDependency1 modelDependency1 = modelDependency1Dao.queryByInsId(JSON.toJSONString(queryMap));
                        if (modelDependency1 != null) {
                            if (StringUtils.isNotEmpty(modelDependency1.getVersion())) {
                                String relativePath = ci4sUsername + "/model/" + modelDependency1.getRepoId() + "/" + modelDependency1.getIdentifier() + "/" + modelDependency1.getVersion() + "/model";
                                modelsService.deleteVersion(modelDependency1.getRepoId(), modelDependency1.getIdentifier(), modelDependency1.getOwner(), modelDependency1.getVersion(), relativePath);
                            } else {
                                modelDependency1Dao.deleteModelById(modelDependency1.getId());
                            }
                        }
                    }
                    //删除导出数据集版本
                    if (key.contains("dataset-export")) {
                        HashMap queryMap = new HashMap<String, Integer>();
                        queryMap.put("ins_id", experimentIns.getId());
                        DatasetTempStorage datasetTempStorage = datasetTempStorageDao.queryByInsId(JSON.toJSONString(queryMap));
                        String relativePath = ci4sUsername + "/datasets/" + datasetTempStorage.getRepoId() + "/" + datasetTempStorage.getName() + "/" + datasetTempStorage.getVersion() + "/dataset";
                        newDatasetService.deleteDatasetVersionNew(datasetTempStorage.getRepoId(), datasetTempStorage.getName(), datasetTempStorage.getCreateBy(), datasetTempStorage.getVersion(), relativePath);
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    /**
     * 查询实验实例日志的单个节点日志
     *
     * @return 运行日志
     */
    @Override
    public String showExperimentInsLog(Integer id, String componentId) {
        //先从map中取出数据

        //先查出实验记录
        ExperimentIns experimentIns = this.experimentInsDao.queryById(id);
        if (experimentIns == null) {
            throw new IllegalStateException("实验实例未查询到，id:" + id);

        }
        String name = experimentIns.getArgoInsName();
        String namespace = experimentIns.getArgoInsNs();

        // 创建请求数据的Json(map)
        Map<String, Object> requestData = new HashMap<>();
        requestData.put("namespace", namespace);
        requestData.put("name", name);
        //先写死这两个数据项
        requestData.put("workflow-type", "workflows");
        requestData.put("artifact-name", "main-logs");
        requestData.put("component-id", componentId);
        // 创建发送数据map，将请求数据作为"data"键的值
        Map<String, Object> res = new HashMap<>();
        res.put("data", requestData);

        try {
            // 发送POST请求到Argo工作流日志查询接口，并将请求数据转换为JSON
            String req = HttpUtils.sendPost(argoUrl + argoWorkflowLog, null, JsonUtils.mapToJson(res));
            // 检查响应是否为空或无内容
            if (StringUtils.isEmpty(req)) {
                throw new RuntimeException("响应内容为空");
            }
            // 将响应的JSON字符串转换为Map对象
            Map<String, Object> runResMap = JsonUtils.jsonToMap(req);
            // 从响应Map中获取"data"的值,也就是日志的值
            String experimentInsLog = (String) runResMap.get("data");
            if (experimentInsLog == null) {
                throw new RuntimeException("日志为空");
            }
            //返回日志内容
            return experimentInsLog;
        } catch (Exception e) {
            throw new RuntimeException("查询实验日志失败: " + e.getMessage(), e);

        }
    }

    @Override
    public List getNodeResult(Integer id, String nodeId) throws Exception {

        List<Map> results = new ArrayList<Map>();
        //查询 实例
        ExperimentIns experimentIns = this.experimentInsDao.queryById(id);
        if (experimentIns == null) {
            throw new Exception("实验实例未查询到，id:" + id);
        }
        //找到 节点 节点结果
        String nodesResultString = experimentIns.getNodesResult();
        if (StringUtils.isEmpty(nodesResultString)) {
            throw new Exception("实验实例未查询到节点结果，id:" + id);
        }
        Map<String, Object> nodesResult = JsonUtils.jsonToMap(nodesResultString);
        Map<String, Object> paramOutput = (Map<String, Object>) nodesResult.get("param_output");
        List<Map<String, Object>> nodeList = (List<Map<String, Object>>) paramOutput.get(nodeId);
        //遍历 查询minio
        for (int i = 0; i < nodeList.size(); i++) {
            Map<String, Object> map = nodeList.get(i);
            String path = (String) map.get("path");
            String bucketName = path.substring(0, path.indexOf("/"));
            String prefix = path.substring(path.indexOf("/") + 1, path.length()) + "/";
            if (StringUtils.equals((String) map.get("type"), "file")) {
                List<Map> fileInfo = minioUtil.listFilesInDirectory(bucketName, prefix);
                map.put("value", fileInfo);
            } else if (StringUtils.equals((String) map.get("type"), "string")) {
                String resultInfo = minioUtil.readObjectAsString(bucketName, prefix);
                map.put("value", resultInfo);
            }
            results.add(map);
            //组装
        }
        return results;
    }

    @Override
    public Map<String, Object> getRealtimeWorkflowLog(LogRequestVo logRequest) {

        String componentId = logRequest.getComponentId();
        String nameSpace = logRequest.getNamespace();
        String name = logRequest.getName();
        String taskId = logRequest.getTaskId();
        String startTime = logRequest.getStartTime();
        // 创建请求数据的Json(map)
        Map<String, Object> requestData = new HashMap<>();
        requestData.put("component_id", componentId);
        requestData.put("namespace", nameSpace);
        requestData.put("name", name);
        requestData.put("task_id", taskId);
        requestData.put("start_time", startTime);
        // 创建发送数据map，将请求数据作为"data"键的值
        Map<String, Object> res = new HashMap<>();
        res.put("data", requestData);

        try {
            // 将Map转换为JSON字符串
            String req = HttpUtils.sendPost(argoUrl + argoWorkflowRealTimeLog, JsonUtils.mapToJson(res));
            // 检查响应是否为空或无内容
            if (StringUtils.isEmpty(req)) {
                throw new RuntimeException("响应内容为空");
            }
            // 使用JacksonUtil将响应字符串转换为Map
            Map<String, Object> tempMap = JacksonUtil.parseJSONStr2Map(req);
            //去掉中间多余的data层
            return (Map<String, Object>) tempMap.get("data");

        } catch (Exception e) {
            throw new RuntimeException("查询实验日志失败: " + e.getMessage(), e);
        }

    }

    @Override
    public Map<String, Object> getRealtimePodLog(String podName, String startTime) {
        Map<String, Object> requestData = new HashMap<>();
        requestData.put("pod_name", podName);
        requestData.put("start_time", startTime);
        try {
            // 将Map转换为JSON字符串
            String req = HttpUtils.sendPost(argoUrl + argoWorkflowPodLog, JsonUtils.mapToJson(requestData));
            // 检查响应是否为空或无内容
            if (StringUtils.isEmpty(req)) {
                throw new RuntimeException("响应内容为空");
            }
            // 使用JacksonUtil将响应字符串转换为Map
            Map<String, Object> tempMap = JacksonUtil.parseJSONStr2Map(req);
            //去掉中间多余的data层
            return (Map<String, Object>) tempMap.get("data");

        } catch (Exception e) {
            throw new RuntimeException("查询pod实时日志失败: " + e.getMessage(), e);
        }

    }

    @Override
    public String getRealtimePodLogFromPod(PodLogVo podLogVo) {
        return k8sClientUtil.getPodLogs(podLogVo.getPodName(), podLogVo.getNamespace(), podLogVo.getContainerName(), logsLines);
    }

    @Override
    public List<ExperimentIns> queryByExperimentIsNotTerminated() {
        return experimentInsDao.queryByExperimentIsNotTerminated();
    }

    @Override
    public Map<String, Long> countByStatus() {
        // 创建一个用于存储状态计数的map
        Map<String, Long> statusCountMap = new HashMap<>();

        // 遍历枚举中的所有状态
        for (ExperimentInsStatus status : ExperimentInsStatus.values()) {
            ExperimentIns experimentIns = new ExperimentIns();
            experimentIns.setStatus(status.toString()); // 设置实例的状态为枚举中的状态

            // 查询具有相同状态的实例数量
            Long count = experimentInsDao.count(experimentIns);

            // 将状态及其对应的实例数量放入map中
            statusCountMap.put(status.toString(), count);
        }

        return statusCountMap;
    }

    private boolean isTerminatedState(ExperimentIns ins) throws IOException {
        // 定义终止态的列表，例如 "Succeeded", "Failed" 等
        String status = ins.getStatus();
        boolean flag = true;
        List<String> terminatedStates = Arrays.asList("Succeeded", Constant.Failed);
        flag = terminatedStates.contains(status);
        if (StringUtils.equals(status, "Terminated")) {
            //如果跟node_status里面不一样，就要去更新node_status的信息
            String nodesStatus = ins.getNodesStatus();
            Map<String, Object> nodeMap = JsonUtils.jsonToMap(nodesStatus);
            String keyStartsWithWorkflow = nodeMap.keySet().stream()
                    .filter(key -> key.startsWith("workflow-"))
                    .findFirst()
                    .orElse(null);
            Map workflowMap = (Map) nodeMap.get(keyStartsWithWorkflow);
            if (workflowMap != null) {
                flag = StringUtils.equals("Terminated", (String) workflowMap.get("phase"));
            }
        }
        return flag;
    }

    public void updateExperimentStatus(Integer experimentId) {
        List<ExperimentIns> insList = getByExperimentId(experimentId);
        List<String> statusList = new ArrayList<>();
        // 更新实验状态列表
        for (int i = 0; i < insList.size(); i++) {
            statusList.add(insList.get(i).getStatus());
        }
        String subStatus = statusList.toString().substring(1, statusList.toString().length() - 1);
        Experiment experiment = experimentDao.queryById(experimentId);
        experiment.setStatusList(subStatus);
        experimentDao.update(experiment);
    }

}


