package com.taais.biz.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.taais.biz.constant.BizConstant;
import com.taais.biz.domain.AlgorithmConfig;
import com.taais.biz.domain.AlgorithmTask;
import com.taais.biz.domain.Data;
import com.taais.biz.domain.bo.*;
import com.taais.biz.domain.dto.AlgorithmConfigParamDto;
import com.taais.biz.domain.dto.task.AlgorithmSubtaskParamDto;
import com.taais.biz.domain.dto.task.CreateTaskDto;
import com.taais.biz.domain.dto.task.DataSelectDto;
import com.taais.biz.domain.dto.task.TaskDto;
import com.taais.biz.domain.vo.AlgorithmTaskVo;
import com.taais.biz.domain.vo.DataVo;
import com.taais.biz.mapper.AlgorithmTaskMapper;
import com.taais.biz.service.*;
import com.taais.common.core.config.TaaisConfig;
import com.taais.common.core.constant.Constants;
import com.taais.common.core.core.page.PageResult;
import com.taais.common.core.utils.MapstructUtils;
import com.taais.common.core.utils.StringUtils;
import com.taais.common.core.utils.file.FileUtils;
import com.taais.common.orm.core.page.PageQuery;
import com.taais.common.orm.core.service.impl.BaseServiceImpl;
import com.taais.system.domain.vo.SysDictDataVo;
import com.taais.system.service.ISysDictDataService;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static com.taais.biz.domain.table.AlgorithmTaskTableDef.ALGORITHM_TASK;

/**
 * 算法任务Service业务层处理
 *
 * @author 0
 * 2024-05-29
 */
@Service
public class AlgorithmTaskServiceImpl extends BaseServiceImpl<AlgorithmTaskMapper, AlgorithmTask> implements IAlgorithmTaskService {

    private static final Logger log = LoggerFactory.getLogger(AlgorithmTaskServiceImpl.class);

    @Resource
    ApplicationContext applicationContext;
    @Resource
    private AlgorithmTaskMapper algorithmTaskMapper;
    @Resource
    private IAlgorithmConfigService algorithmConfigService;
    @Resource
    private IAlgorithmSubtaskService subtaskService;
    @Resource
    private IAlgorithmDataProcessService processService;
    @Resource
    private IAlgorithmBizProcessService bizProcessService;
    @Resource
    private ISysDictDataService dictDataService;
    @Resource
    private IDataService dataService;

    @Override
    public QueryWrapper query() {
        return super.query().from(ALGORITHM_TASK);
    }

    private QueryWrapper buildQueryWrapper(AlgorithmTaskBo algorithmTaskBo) {
        QueryWrapper queryWrapper = super.buildBaseQueryWrapper();
        queryWrapper.and(ALGORITHM_TASK.NAME.like
        (algorithmTaskBo.getName()));
        queryWrapper.and(ALGORITHM_TASK.STATUS.eq
        (algorithmTaskBo.getStatus()));
        queryWrapper.and(ALGORITHM_TASK.START_TIME.eq
        (algorithmTaskBo.getStartTime()));
        queryWrapper.and(ALGORITHM_TASK.END_TIME.eq
        (algorithmTaskBo.getEndTime()));
        queryWrapper.and(ALGORITHM_TASK.COST_SECOND.eq
        (algorithmTaskBo.getCostSecond()));
        return queryWrapper;
    }

    /**
     * 查询算法任务
     *
     * @param id 算法任务主键
     * @return 算法任务
     */
    @Override
    public AlgorithmTaskVo selectById(Long id) {
            return this.getOneAs(query().where(ALGORITHM_TASK.ID.eq(id)), AlgorithmTaskVo.class);
    }

    /**
     * 查询算法任务列表
     *
     * @param algorithmTaskBo 算法任务Bo
     * @return 算法任务集合
     */
    @Override
    public List<AlgorithmTaskVo> selectList(AlgorithmTaskBo algorithmTaskBo) {
        QueryWrapper queryWrapper = buildQueryWrapper(algorithmTaskBo);
            return this.listAs(queryWrapper, AlgorithmTaskVo.class);
    }

    /**
     * 分页查询算法任务列表
     *
     * @param algorithmTaskBo 算法任务Bo
     * @return 分页算法任务集合
     */
    @Override
    public PageResult<AlgorithmTaskVo> selectPage(AlgorithmTaskBo algorithmTaskBo) {
        QueryWrapper queryWrapper = buildQueryWrapper(algorithmTaskBo);
            Page<AlgorithmTaskVo> page = this.pageAs(PageQuery.build(), queryWrapper, AlgorithmTaskVo.class);
        return PageResult.build(page);
    }

    /**
     * 新增算法任务
     *
     * @param algorithmTaskBo 算法任务Bo
     * @return 结果:true 操作成功，false 操作失败
     */
    @Override
    public boolean insert(AlgorithmTaskBo algorithmTaskBo) {
    AlgorithmTask algorithmTask =MapstructUtils.convert(algorithmTaskBo, AlgorithmTask. class);
        boolean save = this.save(algorithmTask);
        algorithmTaskBo.setId(algorithmTask.getId());
        algorithmTaskBo.setVersion(algorithmTask.getVersion());
        return save;//使用全局配置的雪花算法主键生成器生成ID值
    }

    /**
     * 修改算法任务
     *
     * @param algorithmTaskBo 算法任务Bo
     * @return 结果:true 更新成功，false 更新失败
     */
    @Override
    public boolean update(AlgorithmTaskBo algorithmTaskBo) {
        AlgorithmTask algorithmTask =MapstructUtils.convert(algorithmTaskBo, AlgorithmTask. class);
        if (ObjectUtil.isNotNull(algorithmTask) && ObjectUtil.isNotNull(algorithmTask.getId())){
            return this.updateById(algorithmTask);
        }
        return false;
    }

    /**
     * 批量删除算法任务
     *
     * @param ids 需要删除的算法任务主键集合
     * @return 结果:true 删除成功，false 删除失败
     */
    @Transactional
    @Override
    public boolean deleteByIds(Long[] ids) {
        return this.removeByIds(Arrays.asList(ids));
    }

    @Override
    public String create(CreateTaskDto taskDto) {
        // 检查，如果检查不通过返回
        String checkMsg = checkTaskDto(taskDto);
        if (StringUtils.isNotEmpty(checkMsg)){
            return checkMsg;
        }
        // 创建任务
        AlgorithmTaskBo algorithmTask = new AlgorithmTaskBo();
        algorithmTask.setStatus(BizConstant.TASK_STATUS_PENDING);
        algorithmTask.setName(taskDto.getTaskName());
        insert(algorithmTask);
        // 异步处理
        AlgorithmTaskServiceImpl taskService = applicationContext.getBean(AlgorithmTaskServiceImpl.class);
        taskService.processTask(taskDto, algorithmTask);
        return String.valueOf(algorithmTask.getId());
    }

    // task start
    @Override
    public void taskRun() {
        AlgorithmTask algorithmTask = algorithmTaskMapper.getLastTask();
        if(algorithmTask!= null){
            log.info("taskRun start... task id:{}",algorithmTask.getId());
            subtaskService.subtaskRun(algorithmTask.getId());
            log.info("taskRun end... task id:{}",algorithmTask.getId());
        } else {
            log.info("没有可用的算法任务...");
        }
    }

    private String checkTaskDto(CreateTaskDto taskDto) {
        // todo check taskDto
        return null;
    }

    @Async
    public void processTask(CreateTaskDto taskDto, AlgorithmTaskBo algorithmTask) {
        // 训练
        List<String> trainDataFolderPathList = Collections.emptyList();
        // 2 如果有该，则获取训练数据
        List<String> selectTask = taskDto.getSelectTask();

        if (selectTask.contains(BizConstant.STEP2_TRAIN_DATA_SELECT)) {
            trainDataFolderPathList = getTrainDataSet(algorithmTask, taskDto);
        }
        // 3 如果有该，训练数据增强
        if (selectTask.contains(BizConstant.STEP3_TRAIN_DATA_ENHANCEMENT)) {
            trainDataFolderPathList = createTrainDataEnhancementSubtask(algorithmTask, taskDto, trainDataFolderPathList);
        }
        // 4 如果有该，训练数据扩充
        if (selectTask.contains(BizConstant.STEP4_TRAIN_DATA_EXPANSION)) {
            trainDataFolderPathList = createTrainDataExpansionSubtask(algorithmTask, taskDto, trainDataFolderPathList);
        }
        // 5 如果有该，训练
        if (selectTask.contains(BizConstant.STEP5_TRAIN)) {
            createTrainSubtask(algorithmTask, taskDto, trainDataFolderPathList);
        }
        // 测试
        // 6 如果有该，则获取测试数据
        List<String> testDataFolderPathList = Collections.emptyList();
        if (selectTask.contains(BizConstant.STEP6_TEST_DATA_SELECT)) {
            testDataFolderPathList = getTestDataSet(algorithmTask, taskDto);
        }
        // 7 如果有该，训练测试增强
        if (selectTask.contains(BizConstant.STEP7_TEST_DATA_ENHANCEMENT)) {
            testDataFolderPathList = createTestDataEnhancementSubtask(algorithmTask, taskDto, testDataFolderPathList);
        }
        // 8 如果有该，训练测试扩充
        if (selectTask.contains(BizConstant.STEP8_TEST_DATA_EXPANSION)) {
            testDataFolderPathList = createTestDataExpansionSubtask(algorithmTask, taskDto, testDataFolderPathList);
        }
        // 9 如果有该，测试
        if (selectTask.contains(BizConstant.STEP9_TEST)) {
            createTestSubtask(algorithmTask, taskDto, testDataFolderPathList);
        }

        // 推理
        List<String> reasoningDataFolderPathList = Collections.emptyList();
        // 10 如果有该，则获取推理数据
        if (selectTask.contains(BizConstant.STEP10_REASONING_DATA_SELECT)) {
            reasoningDataFolderPathList = getReasoningDataSet(algorithmTask, taskDto);
        }
        // 11 如果有该，推理数据增强
        if (selectTask.contains(BizConstant.STEP11_REASONING_DATA_ENHANCEMENT)) {
            reasoningDataFolderPathList = createReasoningDataEnhancementSubtask(algorithmTask, taskDto, reasoningDataFolderPathList);
        }
        // 12 如果有该，推理数据扩充
        if (selectTask.contains(BizConstant.STEP12_REASONING_DATA_EXPANSION)) {
            reasoningDataFolderPathList = createReasoningDataExpansionSubtask(algorithmTask, taskDto, reasoningDataFolderPathList);
        }
        // 13 如果有该，推理
        if (selectTask.contains(BizConstant.STEP13_REASONING)) {
            createReasoningSubtask(algorithmTask, taskDto, reasoningDataFolderPathList);
        }
        log.info("=========================创建结束===============================");
    }

    private void createTestSubtask(AlgorithmTaskBo algorithmTask, CreateTaskDto taskDto, List<String> testDataFolderPathList) {
        // 创建subtask
        AlgorithmSubtaskBo algorithmSubtask = BuildAlgorithmSubtaskBo(algorithmTask, BizConstant.STEP9_TEST);
        subtaskService.insert(algorithmSubtask);
        Long index = 0L;
        for (String testDataFolderPath : testDataFolderPathList) {
            for (TaskDto dto : taskDto.getTest()) {
                // 创建算法处理任务
                AlgorithmBizProcessBo algorithmBizProcessBo = new AlgorithmBizProcessBo();
                AlgorithmConfig algorithmConfig = algorithmConfigService.getById(dto.getAlgorithmId());
                algorithmBizProcessBo.setName(algorithmConfig != null ? algorithmConfig.getAlgorithmName() : null);
                algorithmBizProcessBo.setAlgorithmId(dto.getAlgorithmId());
                algorithmBizProcessBo.setModelId(dto.getModelId());
                algorithmBizProcessBo.setStatus(BizConstant.TASK_STATUS_PENDING);
                algorithmBizProcessBo.setPreprocessPath(testDataFolderPath);
                algorithmBizProcessBo.setIndex(index);
                algorithmBizProcessBo.setSubTaskId(algorithmSubtask.getId());
                bizProcessService.insert(algorithmBizProcessBo);

                // 组装结果路径 并更新结果路径和参数
                String resultPath = BizConstant.TASK_FOLDER_PATH_HEAD + algorithmTask.getId()
                    + BizConstant.TASK_FOLDER_PATH_MID_TEST + BizConstant.TASK_FOLDER_PATH_TRAIL_RESULT + algorithmBizProcessBo.getId() + "/";
                resultPath = resultPath.replaceAll("//", "/");
//                String finallyParams = buildFinallyParams(dto.getParams(), testDataFolderPath, resultPath);
                algorithmBizProcessBo.setResultPath(resultPath);
                algorithmBizProcessBo.setParameters(dto.getParams());
                algorithmBizProcessBo.setLog(resultPath+BizConstant.TASK_FOLDER_LOG_PATH);
                bizProcessService.update(algorithmBizProcessBo);
                index++;
            }
        }
    }

    private List<String> createTestDataExpansionSubtask(AlgorithmTaskBo algorithmTask, CreateTaskDto taskDto, List<String> testDataFolderPathList) {
        List<String> returnList = new ArrayList<>();
        // 创建subtask
        AlgorithmSubtaskBo algorithmSubtask = BuildAlgorithmSubtaskBo(algorithmTask, BizConstant.STEP8_TEST_DATA_EXPANSION);
        subtaskService.insert(algorithmSubtask);
        long index = 0;
        for(String testDataFolderPath : testDataFolderPathList){
            // 创建数据扩展任务
            AlgorithmDataProcessBo processBo = new AlgorithmDataProcessBo();
            processBo.setAlgorithmId(taskDto.getTestDataEnhancement().getAlgorithmId());
            processBo.setSubTaskId(algorithmSubtask.getId());
            processBo.setStatus(BizConstant.TASK_STATUS_PENDING);
            processBo.setPreprocessPath(testDataFolderPath);
            processBo.setIndex(index);
            processService.insert(processBo);

            // 组装结果路径 更新参数和结果路径
            String resultPath = BizConstant.TASK_FOLDER_PATH_HEAD + algorithmTask.getId()
                + BizConstant.TASK_FOLDER_PATH_MID_TEST + BizConstant.TASK_FOLDER_PATH_TRAIL_EXPANSION + processBo.getId() + "/";
            resultPath = resultPath.replaceAll("//", "/");
//            String finallyParams = buildFinallyParams(taskDto.getTestDataExpansion().getParams(), testDataFolderPath, resultPath);
            processBo.setResultPath(resultPath);
            processBo.setParameters(taskDto.getTestDataExpansion().getParams());
            processBo.setLog(resultPath+BizConstant.TASK_FOLDER_LOG_PATH);
            processService.update(processBo);
            returnList.add(resultPath);
            index++;
        }
        return returnList;
    }

    private List<String> createTestDataEnhancementSubtask(AlgorithmTaskBo algorithmTask, CreateTaskDto taskDto, List<String> testDataFolderPathList) {
        List<String> returnList = new ArrayList<>();
        // 创建subtask
        AlgorithmSubtaskBo algorithmSubtask = BuildAlgorithmSubtaskBo(algorithmTask, BizConstant.STEP7_TEST_DATA_ENHANCEMENT);
        subtaskService.insert(algorithmSubtask);
        Long index = 0L;
        // 创建数据加强任务
        for (String testDataFolderPath : testDataFolderPathList) {
            // 创建数据增强任务
            AlgorithmDataProcessBo processBo = new AlgorithmDataProcessBo();
            processBo.setAlgorithmId(taskDto.getTestDataEnhancement().getAlgorithmId());
            processBo.setSubTaskId(algorithmSubtask.getId());
            processBo.setStatus(BizConstant.TASK_STATUS_PENDING);
            processBo.setPreprocessPath(testDataFolderPath);
            processBo.setIndex(index);
            processService.insert(processBo);

            // 组装结果路径 并更新参数和结果路径
            String resultPath = BizConstant.TASK_FOLDER_PATH_HEAD + algorithmTask.getId()
                + BizConstant.TASK_FOLDER_PATH_MID_TEST + BizConstant.TASK_FOLDER_PATH_TRAIL_ENHANCEMENT + processBo.getId() + "/";
            resultPath = resultPath.replaceAll("//", "/");
            // create AlgorithmDataProcess 创建数据处理
//            String finallyParams = buildFinallyParams(taskDto.getTestDataEnhancement().getParams(), testDataFolderPath, resultPath);
            processBo.setResultPath(resultPath);
            processBo.setParameters(taskDto.getTestDataEnhancement().getParams());
            processBo.setLog(resultPath+BizConstant.TASK_FOLDER_LOG_PATH);
            processService.update(processBo);
            returnList.add(resultPath);
            index++;
        }


        return returnList;
    }

    private List<String> getTestDataSet(AlgorithmTaskBo algorithmTask, CreateTaskDto taskDto) {
        List<String> returnList = new ArrayList<>();
        // 获取条件
        List<DataSelectDto> testDataSelectList = taskDto.getTestDataSelect();
        long index = 0L;
        for (DataSelectDto testDataSelect : testDataSelectList) {
            // 获取数据集
            List<DataVo> testDataList = getDataListByDataSelect(testDataSelect);

            String destinationPath = BizConstant.TASK_FOLDER_PATH_HEAD + algorithmTask.getId()
                + BizConstant.TASK_FOLDER_PATH_MID_TEST + BizConstant.TASK_FOLDER_PATH_TRAIL_ORIGINAL + index + "/";
            destinationPath = destinationPath.replaceAll("//", "/");
            // 同步到文件夹
            copyToDestinationFolder(testDataList, destinationPath);
            returnList.add(destinationPath);
            index++;
        }
        return returnList;
    }

    private void createReasoningSubtask(AlgorithmTaskBo algorithmTask, CreateTaskDto taskDto, List<String> reasoningDataFolderPathList) {
        // 创建subtask
        AlgorithmSubtaskBo algorithmSubtask = BuildAlgorithmSubtaskBo(algorithmTask, BizConstant.STEP13_REASONING);
        subtaskService.insert(algorithmSubtask);
        Long index = 0L;
        for (String reasoningDataFolderPath : reasoningDataFolderPathList) {
            for (TaskDto dto : taskDto.getReasoning()) {
                // 创建算法处理任务
                AlgorithmBizProcessBo algorithmBizProcessBo = new AlgorithmBizProcessBo();
                AlgorithmConfig algorithmConfig = algorithmConfigService.getById(dto.getAlgorithmId());
                algorithmBizProcessBo.setName(algorithmConfig != null ? algorithmConfig.getAlgorithmName() : null);
                algorithmBizProcessBo.setAlgorithmId(dto.getAlgorithmId());
                algorithmBizProcessBo.setModelId(dto.getModelId());
                algorithmBizProcessBo.setStatus(BizConstant.TASK_STATUS_PENDING);
                algorithmBizProcessBo.setPreprocessPath(reasoningDataFolderPath + BizConstant.IMAGE);
                algorithmBizProcessBo.setIndex(index);
                algorithmBizProcessBo.setSubTaskId(algorithmSubtask.getId());
                bizProcessService.insert(algorithmBizProcessBo);

                // 组装结果路径 并更新结果路径和参数
                String resultPath = BizConstant.TASK_FOLDER_PATH_HEAD + algorithmTask.getId()
                    + BizConstant.TASK_FOLDER_PATH_MID_REASONING + BizConstant.TASK_FOLDER_PATH_TRAIL_RESULT + algorithmBizProcessBo.getId() + "/";
                resultPath = resultPath.replaceAll("//", "/");
//                String finallyParams = buildFinallyParams(dto.getParams(), reasoningDataFolderPath, resultPath);
                algorithmBizProcessBo.setResultPath(resultPath);
                algorithmBizProcessBo.setParameters(dto.getParams());
                algorithmBizProcessBo.setLog(resultPath+BizConstant.TASK_FOLDER_LOG_PATH);
                bizProcessService.update(algorithmBizProcessBo);
                index++;
            }
        }
    }

    private List<String> createReasoningDataExpansionSubtask(AlgorithmTaskBo algorithmTask, CreateTaskDto taskDto, List<String> reasoningDataFolderPathList) {
        List<String> returnList = new ArrayList<>();
        // 创建subtask
        AlgorithmSubtaskBo algorithmSubtask = BuildAlgorithmSubtaskBo(algorithmTask, BizConstant.STEP12_REASONING_DATA_EXPANSION);
        subtaskService.insert(algorithmSubtask);
        long index = 0;
        for(String reasoningDataFolderPath : reasoningDataFolderPathList){
            // 创建数据扩展任务
            AlgorithmDataProcessBo processBo = new AlgorithmDataProcessBo();
            processBo.setAlgorithmId(taskDto.getReasoningDataEnhancement().getAlgorithmId());
            processBo.setSubTaskId(algorithmSubtask.getId());
            processBo.setStatus(BizConstant.TASK_STATUS_PENDING);
            processBo.setPreprocessPath(reasoningDataFolderPath);
            processBo.setIndex(index);
            processService.insert(processBo);

            // 组装结果路径 更新参数和结果路径
            String resultPath = BizConstant.TASK_FOLDER_PATH_HEAD + algorithmTask.getId()+"/"
                + BizConstant.TASK_FOLDER_PATH_MID_REASONING + BizConstant.TASK_FOLDER_PATH_TRAIL_EXPANSION + processBo.getId() + "/";
            resultPath = resultPath.replaceAll("//", "/");
//            String finallyParams = buildFinallyParams(taskDto.getReasoningDataExpansion().getParams(), reasoningDataFolderPath, resultPath);
            processBo.setResultPath(resultPath);
            processBo.setParameters(taskDto.getReasoningDataExpansion().getParams());
            processBo.setLog(resultPath+BizConstant.TASK_FOLDER_LOG_PATH);
            processService.update(processBo);
            returnList.add(resultPath);
            index++;
        }


        return returnList;
    }

    private List<String> createReasoningDataEnhancementSubtask(AlgorithmTaskBo algorithmTask, CreateTaskDto taskDto, List<String> reasoningDataFolderPathList) {

        List<String> returnList = new ArrayList<>();
        // 创建subtask
        AlgorithmSubtaskBo algorithmSubtask = BuildAlgorithmSubtaskBo(algorithmTask, BizConstant.STEP11_REASONING_DATA_ENHANCEMENT);
        subtaskService.insert(algorithmSubtask);
        Long index = 0L;
        // 创建数据加强任务
        for (String reasoningDataFolderPath : reasoningDataFolderPathList) {
            // 创建数据增强任务
            AlgorithmDataProcessBo processBo = new AlgorithmDataProcessBo();
            processBo.setAlgorithmId(taskDto.getReasoningDataEnhancement().getAlgorithmId());
            processBo.setSubTaskId(algorithmSubtask.getId());
            processBo.setStatus(BizConstant.TASK_STATUS_PENDING);
            processBo.setPreprocessPath(reasoningDataFolderPath);
            processBo.setIndex(index);
            processService.insert(processBo);

            // 组装结果路径 并更新参数和结果路径
            String resultPath = BizConstant.TASK_FOLDER_PATH_HEAD + algorithmTask.getId() + "/"
                + BizConstant.TASK_FOLDER_PATH_MID_REASONING + BizConstant.TASK_FOLDER_PATH_TRAIL_ENHANCEMENT + processBo.getId() + "/";
            resultPath = resultPath.replaceAll("//", "/");
            // create AlgorithmDataProcess 创建数据处理
//            String finallyParams = buildFinallyParams(taskDto.getReasoningDataEnhancement().getParams(), reasoningDataFolderPath, resultPath);
            processBo.setResultPath(resultPath);
            processBo.setParameters(taskDto.getReasoningDataEnhancement().getParams());
            processBo.setLog(resultPath+BizConstant.TASK_FOLDER_LOG_PATH);
            processService.update(processBo);
            returnList.add(resultPath);
            index++;
        }


        return returnList;
    }

    private List<String> getReasoningDataSet(AlgorithmTaskBo algorithmTask, CreateTaskDto taskDto) {
        List<String> returnList = new ArrayList<>();
        // 获取条件
        List<DataSelectDto> reasoningDataSelectList = taskDto.getReasoningDataSelect();
        long index = 0L;
        for (DataSelectDto reasoningDataSelect : reasoningDataSelectList) {
            // 获取数据集
            List<DataVo> reasoningDataList = getDataListByDataSelect(reasoningDataSelect);

            String destinationPath = BizConstant.TASK_FOLDER_PATH_HEAD + algorithmTask.getId()
                + BizConstant.TASK_FOLDER_PATH_MID_REASONING + BizConstant.TASK_FOLDER_PATH_TRAIL_ORIGINAL + index + "/";
            destinationPath = destinationPath.replaceAll("//", "/");
            // 同步到文件夹
            copyToDestinationFolder(reasoningDataList, destinationPath);
            returnList.add(destinationPath);
            index++;
        }

        return returnList;
    }

    private List<String> createTrainDataEnhancementSubtask(AlgorithmTaskBo algorithmTask, CreateTaskDto taskDto, List<String> trainDataFolderPathList) {
        List<String> returnList = new ArrayList<>();
        // 创建subtask
        AlgorithmSubtaskBo algorithmSubtask = BuildAlgorithmSubtaskBo(algorithmTask, BizConstant.STEP3_TRAIN_DATA_ENHANCEMENT);
        subtaskService.insert(algorithmSubtask);
        Long index = 0L;
        // 创建数据加强任务
        for (String trainDataFolderPath : trainDataFolderPathList) {
            // 创建数据增强任务
            AlgorithmDataProcessBo processBo = new AlgorithmDataProcessBo();
            processBo.setAlgorithmId(taskDto.getTrainDataEnhancement().getAlgorithmId());
            processBo.setSubTaskId(algorithmSubtask.getId());
            processBo.setStatus(BizConstant.TASK_STATUS_PENDING);
            processBo.setPreprocessPath(trainDataFolderPath);
            processBo.setIndex(index);
            processService.insert(processBo);

            // 组装结果路径 并更新参数和结果路径
            String resultPath = BizConstant.TASK_FOLDER_PATH_HEAD + algorithmTask.getId()
                + BizConstant.TASK_FOLDER_PATH_MID_TRAIN + BizConstant.TASK_FOLDER_PATH_TRAIL_ENHANCEMENT + processBo.getId() + "/";
            resultPath = resultPath.replaceAll("//", "/");
            // create AlgorithmDataProcess 创建数据处理
//            String finallyParams = buildFinallyParams(taskDto.getTrainDataEnhancement().getParams(), trainDataFolderPath, resultPath);
            processBo.setResultPath(resultPath);
            processBo.setParameters(taskDto.getTrainDataEnhancement().getParams());
            processBo.setLog(resultPath+BizConstant.TASK_FOLDER_LOG_PATH);
            processService.update(processBo);
            returnList.add(resultPath);
            index++;
        }


        return returnList;
    }

    private void createTrainSubtask(AlgorithmTaskBo algorithmTask, CreateTaskDto taskDto, List<String> trainDataFolderPathList) {
        // 创建subtask
        AlgorithmSubtaskBo algorithmSubtask = BuildAlgorithmSubtaskBo(algorithmTask, BizConstant.STEP5_TRAIN);
        subtaskService.insert(algorithmSubtask);
        Long index = 0L;
        for (String trainDataFolderPath : trainDataFolderPathList) {
            for (TaskDto dto : taskDto.getTrain()) {
                // 创建算法处理任务
                AlgorithmBizProcessBo algorithmBizProcessBo = new AlgorithmBizProcessBo();
                AlgorithmConfig algorithmConfig = algorithmConfigService.getById(dto.getAlgorithmId());
                algorithmBizProcessBo.setName(algorithmConfig != null ? algorithmConfig.getAlgorithmName() : null);
                algorithmBizProcessBo.setAlgorithmId(dto.getAlgorithmId());
                algorithmBizProcessBo.setModelId(dto.getModelId());
                algorithmBizProcessBo.setStatus(BizConstant.TASK_STATUS_PENDING);
                algorithmBizProcessBo.setPreprocessPath(trainDataFolderPath);
                algorithmBizProcessBo.setIndex(index);
                algorithmBizProcessBo.setSubTaskId(algorithmSubtask.getId());
                bizProcessService.insert(algorithmBizProcessBo);

                // 组装结果路径 并更新结果路径和参数
                String resultPath = BizConstant.TASK_FOLDER_PATH_HEAD + algorithmTask.getId()
                    + BizConstant.TASK_FOLDER_PATH_MID_TRAIN + BizConstant.TASK_FOLDER_PATH_TRAIL_RESULT + algorithmBizProcessBo.getId() + "/";
                resultPath = resultPath.replaceAll("//", "/");
//                String finallyParams = buildFinallyParams(dto.getParams(), trainDataFolderPath, resultPath);
                algorithmBizProcessBo.setResultPath(resultPath);
                algorithmBizProcessBo.setParameters(dto.getParams());
                algorithmBizProcessBo.setLog(resultPath+BizConstant.TASK_FOLDER_LOG_PATH);
                bizProcessService.update(algorithmBizProcessBo);
                index++;
            }
        }
    }

    private List<String> createTrainDataExpansionSubtask(AlgorithmTaskBo algorithmTask, CreateTaskDto taskDto, List<String> trainDataFolderPathList) {
        List<String> returnList = new ArrayList<>();
        // 创建subtask
        AlgorithmSubtaskBo algorithmSubtask = BuildAlgorithmSubtaskBo(algorithmTask, BizConstant.STEP4_TRAIN_DATA_EXPANSION);
        subtaskService.insert(algorithmSubtask);
        long index = 0;
        for(String trainDataFolderPath : trainDataFolderPathList){
            // 创建数据扩展任务
            AlgorithmDataProcessBo processBo = new AlgorithmDataProcessBo();
            processBo.setAlgorithmId(taskDto.getTrainDataEnhancement().getAlgorithmId());
            processBo.setSubTaskId(algorithmSubtask.getId());
            processBo.setStatus(BizConstant.TASK_STATUS_PENDING);
            processBo.setPreprocessPath(trainDataFolderPath);
            processBo.setIndex(index);
            processService.insert(processBo);

            // 组装结果路径 更新参数和结果路径
            String resultPath = BizConstant.TASK_FOLDER_PATH_HEAD + algorithmTask.getId()
                + BizConstant.TASK_FOLDER_PATH_MID_TRAIN + BizConstant.TASK_FOLDER_PATH_TRAIL_EXPANSION + processBo.getId() + "/";
            resultPath = resultPath.replaceAll("//", "/");
//            String finallyParams = buildFinallyParams(taskDto.getTrainDataExpansion().getParams(), trainDataFolderPath, resultPath);
            processBo.setResultPath(resultPath);
            processBo.setParameters(taskDto.getTrainDataExpansion().getParams());
            processBo.setLog(resultPath+BizConstant.TASK_FOLDER_LOG_PATH);
            processService.update(processBo);
            returnList.add(resultPath);
            index++;
        }
        return returnList;
    }

    private static AlgorithmSubtaskBo BuildAlgorithmSubtaskBo(AlgorithmTaskBo algorithmTask, String step) {
        AlgorithmSubtaskBo algorithmSubtask = new AlgorithmSubtaskBo();
        algorithmSubtask.setTaskId(algorithmTask.getId());
        algorithmSubtask.setIndex(Long.valueOf(step));
        algorithmSubtask.setParameters("null");
        // todo allen
        switch (step) {
            case BizConstant.STEP5_TRAIN -> {
                algorithmSubtask.setName(BizConstant.TASK_BIZ_AG_TYPE1_CN);
                algorithmSubtask.setType(BizConstant.TASK_BIZ_AG_TYPE1_CODE);
            }
            case BizConstant.STEP9_TEST -> {
                algorithmSubtask.setName(BizConstant.TASK_BIZ_AG_TYPE2_CN);
                algorithmSubtask.setType(BizConstant.TASK_BIZ_AG_TYPE2_CODE);
            }
            case BizConstant.STEP13_REASONING -> {
                algorithmSubtask.setName(BizConstant.TASK_BIZ_AG_TYPE3_CN);
                algorithmSubtask.setType(BizConstant.TASK_BIZ_AG_TYPE3_CODE);
            }
            default -> log.warn("BuildAlgorithmSubtaskBo 这块出现了一些错误，step：{}", step);
        }
        algorithmSubtask.setStatus(BizConstant.TASK_STATUS_PENDING);
        return algorithmSubtask;
    }

    private static String buildFinallyParams(String params, String trainDataFolderPath, String resultPath) {
        AlgorithmSubtaskParamDto algorithmSubtaskParamDto = new AlgorithmSubtaskParamDto();
        algorithmSubtaskParamDto.setSourcePath(trainDataFolderPath);
        algorithmSubtaskParamDto.setResultPath(resultPath);
        Gson gson = new Gson();
        List<AlgorithmConfigParamDto> otherParams = gson.fromJson(params, new TypeToken<List<AlgorithmConfigParamDto>>() {}.getType());
        algorithmSubtaskParamDto.setOtherParams(otherParams);

        // 将User对象转换为JSON字符串
        return gson.toJson(algorithmSubtaskParamDto);
    }

    private List<String> getTrainDataSet(AlgorithmTaskBo algorithmTask, CreateTaskDto taskDto) {
        List<String> returnList = new ArrayList<>();
        // 获取条件
        List<DataSelectDto> trainDataSelectList = taskDto.getTrainDataSelect();
        long index = 0L;
        for (DataSelectDto trainDataSelect : trainDataSelectList) {
            // 获取数据集
            List<DataVo> trainDataList = getDataListByDataSelect(trainDataSelect);

            String destinationPath = BizConstant.TASK_FOLDER_PATH_HEAD + algorithmTask.getId()
                + BizConstant.TASK_FOLDER_PATH_MID_TRAIN + BizConstant.TASK_FOLDER_PATH_TRAIL_ORIGINAL + index + "/";
            // 同步到文件夹
            destinationPath = destinationPath.replaceAll("//", "/");
            copyToDestinationFolder(trainDataList, destinationPath);
            returnList.add(destinationPath);
            index++;
        }
        return returnList;
    }

    private void copyToDestinationFolder(List<DataVo> trainDataList, String destinationPath) {
//        SysDictDataVo sysDictDataVo = dictDataService.selectDictDataByTypeAndLabel("biz_algorithm_config", "path");
//        if (sysDictDataVo!= null && StringUtils.isNotEmpty(sysDictDataVo.getDictValue())) {
//            destinationBase = sysDictDataVo.getDictValue();
//        }
        int errorCount = 0;
        for (DataVo dataVo : trainDataList) {
            // 复制图片
            String imagePath = TaaisConfig.getProfile() + StringUtils.substringAfter(dataVo.getUrl(), Constants.RESOURCE_PREFIX);
            String destPath = TaaisConfig.getProfile() + destinationPath+BizConstant.IMAGE;
            String osName = System.getProperty("os.name").toLowerCase();
            try {
                if (osName.contains("win")) {
                } else {
                    // Linux/Unix 环境
                    imagePath = imagePath.replaceAll("\\\\", "/");
                    destPath = destPath.replaceAll("\\\\", "/");
                }
                FileUtils.copyFile(imagePath, destPath);
                log.info("复制图片文件成功source：{}，target：{}", imagePath, destPath);
            } catch (IOException e) {
                errorCount++;
                log.error("复制图片文件出错source：{}，target：{}", imagePath, destPath, e);
            }
            if(dataVo.getLabeled()){
                String txtPathStr = FileUtils.getTxtPathStr(imagePath);
                String destLabelPath = TaaisConfig.getProfile() + destinationPath+BizConstant.LABEL;
                if (osName.contains("win")) {
                } else {
                    // Linux/Unix 环境
                    txtPathStr = txtPathStr.replaceAll("\\\\", "/");
                    destLabelPath = destLabelPath.replaceAll("\\\\", "/");
                }
                try {
                    FileUtils.copyFile(txtPathStr, destLabelPath);
                    log.info("复制标注文件成功source：{}，target：{}", imagePath, destLabelPath);
                } catch (IOException e) {
                    errorCount++;
                    log.error("复制标注文件出错source：{}，target：{}", txtPathStr, destLabelPath,e);
                }
            }

        }
        if(errorCount != 0){
            log.warn("复制文件失败了{}个!!",errorCount);
        }
    }

    private List<DataVo> getDataListByDataSelect(DataSelectDto trainDataSelect) {
        String condition = trainDataSelect.getCondition();
        if(trainDataSelect.getConditionSelected()){
            Gson gson = new Gson();
            DataBo data = gson.fromJson(condition, DataBo.class);
            return dataService.selectList(data);
        } else {
            List<Data> data = dataService.selectByIds(trainDataSelect.getDateSet());
            return MapstructUtils.convert(data, DataVo. class);
        }
    }
}
