package com.css.simulation.resource.server.app.impl;

import api.common.pojo.common.PageVO;
import api.common.pojo.common.ResponseBodyVO;
import api.common.pojo.constants.DictConstants;
import api.common.pojo.constants.ProjectConstants;
import api.common.pojo.enums.MultiSimulationResultTypeEnum;
import api.common.pojo.enums.MultiSimulationStatusEnum;
import api.common.pojo.enums.MultiSimulationTaskStatusEnum;
import api.common.pojo.param.KafkaParameter;
import api.common.pojo.param.MinioParameter;
import api.common.pojo.param.project.*;
import api.common.pojo.po.algorithm.AlgorithmPO;
import api.common.pojo.po.model.ConfigPO;
import api.common.pojo.po.project.MultiSimulationProjectPO;
import api.common.pojo.po.project.MultiSimulationProjectTaskRecordPO;
import api.common.pojo.po.project.MultiSimulationScenePO;
import api.common.pojo.po.project.SimulationManualProjectPO;
import api.common.pojo.vo.map.SimulationMapPathVO;
import api.common.pojo.vo.map.SimulationMapVO;
import api.common.pojo.vo.project.*;
import api.common.util.JsonUtil;
import api.common.util.StringUtil;
import api.common.util.TimeUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.css.simulation.resource.server.app.service.job_manage.MultiSimulationProjectService;
import com.css.simulation.resource.server.infra.db.mysql.mapper.*;
import com.css.simulation.resource.server.infra.feign.service.FileDownService;
import com.css.simulation.resource.server.infra.util.AuthUtil;
import com.css.simulation.resource.server.infra.util.PageUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import feign.Response;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Service
@Slf4j
public class MultiSimulationProjectServiceImpl implements MultiSimulationProjectService {

    @Resource
    private MultiSimulationProjectMapper multiSimulationProjectMapper;
    @Resource
    private MultiSimulationProjectTaskRecordMapper taskRecordMapper;
    @Resource
    private MultiSimulationSceneMapper simulationSceneMapper;

    @Resource
    private MultiSimulationSceneCarMapper sceneCarMapper;

    @Resource
    private SimulationMapMapper mapMapper;
    @Resource
    private SimulationMapPathMapper mapPathMapper;

    @Resource
    private SimulationManualProjectMapper simulationManualProjectMapper;

    @Resource
    private MultiSimulationProjectResultMapper resultMapper;

    @Resource
    private KafkaTemplate<String, String> kafkaTemplate;

    @Value("${multi-download-task-temp-path}")
    private String multiDownloadTaskTempPath;

    @Resource
    private FileDownService fileDownService;


    @Override
    @SneakyThrows
    public ResponseBodyVO<PageInfo<MultiSimulationProjectVO>> selectMultiSimulationProject(MultiSimulationProjectParam param) {
        if (Objects.isNull(param.getPageNum())) {
            param.setPageNum(1);
        }
        if (Objects.isNull(param.getPageSize())) {
            param.setPageSize(10);
        }
        if (StringUtils.isBlank(param.getProjectName())) {
            param.setProjectName(null);
        }
        if (StringUtils.isBlank(param.getProjectKey())) {
            param.setProjectKey(null);
        }
        if (StringUtils.isBlank(param.getProjectId())) {
            param.setProjectId(null);
        }
        setPage(param.getPageNum(), param.getPageSize());
        List<MultiSimulationProjectVO> multiSimulationProjectVOS = multiSimulationProjectMapper.selectProjectList(param);
        if (!CollectionUtils.isEmpty(multiSimulationProjectVOS)) {
            for (MultiSimulationProjectVO project : multiSimulationProjectVOS) {
                String id = project.getId();
                project.setProjectStatusValue(MultiSimulationStatusEnum.matchStatusEnumByStatus(project.getProjectStatus()).getProjectStatusValue());
                int i = simulationSceneMapper.selectSceneNumsByProjectId(id);
                project.setSceneNums(i);
            }
        }
        PageInfo<MultiSimulationProjectVO> pageInfo = new PageInfo<>(multiSimulationProjectVOS);
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, pageInfo);
    }

    @Override
    @SneakyThrows
    public ResponseBodyVO<MultiSimulationProjectDetailVO> addMultiSimulationProject(MultiSimulationProjectParam param) {
        String name = param.getProjectName();

        MultiSimulationProjectVO multiSimulationProjectVO = multiSimulationProjectMapper.selectMultiSimulationProjectByName(StringUtils.isBlank(name) ? "" : name);
        if (!Objects.isNull(multiSimulationProjectVO)) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "添加失败,存在同名的多模式仿真任务");
        }
        String currentUserId = AuthUtil.getCurrentUserId();

        MultiSimulationProjectPO build = MultiSimulationProjectPO.builder()
            .id(StringUtil.getRandomUUID())
            .projectName(param.getProjectName() == null ? "" : param.getProjectName())
            .projectMaxSeconds(param.getProjectMaxSeconds() == null ? 0 : param.getProjectMaxSeconds())
            .projectKey(param.getProjectKey() == null ? "" : param.getProjectKey())
            .projectDescription(param.getProjectDescription() == null ? "" : param.getProjectDescription())
            .projectUserId(currentUserId)
            .projectStatus(MultiSimulationStatusEnum.INIT_STATUS.getProjectStatus())
            .build();
        int i = multiSimulationProjectMapper.addMultiSimulationProject(build);
        if (i > 0) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, MultiSimulationProjectDetailVO.builder().projectId(build.getId()).build());
        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SERVER_FAILURE);
    }

    @Override
    @SneakyThrows
    public ResponseBodyVO<String> deleteMultiSimulationProject(MultiSimulationProjectParam param) {
        int i = multiSimulationProjectMapper.deleteMultiSimulationProject(param.getProjectId());
        if (i > 0) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, null);
        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SERVER_FAILURE);
    }

    @Override
    @SneakyThrows
    public ResponseBodyVO updateMultiSimulationProjectStatus(MultiSimulationProjectParam param){
        String projectId = param.getProjectId();
        MultiSimulationProjectVO projectVO = multiSimulationProjectMapper.selectMultiSimulationProjectById(projectId);
        if (Objects.isNull(projectVO)){
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "未查询到可用的任务");
        }
        Integer projectStatus = projectVO.getProjectStatus();
        Integer status = param.getProjectStatus();
        int res = 0;
        if (projectStatus == MultiSimulationStatusEnum.INIT_STATUS.getProjectStatus() || projectStatus == MultiSimulationStatusEnum.TERMINATED_STATUS.getProjectStatus()){
            if (status != MultiSimulationStatusEnum.RUN_STATUS.getProjectStatus()){
                return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "当前任务状态不允许执行此操作");
            }
            // 校验参数
            MultiSimulationSceneParam multiSimulationSceneParam = new MultiSimulationSceneParam();
            multiSimulationSceneParam.setProjectId(projectId);
            List<MultiSimulationSceneVO> multiSimulationSceneVOS = simulationSceneMapper.selectSceneList(multiSimulationSceneParam);
            ResponseBodyVO responseBodyVO = checkAllScene(multiSimulationSceneVOS);
            if (responseBodyVO.getCode() != ResponseBodyVO.Response.SUCCESS.getCode()){
                return responseBodyVO;
            }
            for (MultiSimulationSceneVO sceneVo: multiSimulationSceneVOS) {
                String sceneVoId = sceneVo.getId();
                String mapId = sceneVo.getMapId();
                SimulationMapVO simulationMapVO = mapMapper.selectMapByMapId(mapId);
                if (Objects.isNull(simulationMapVO)){
                    return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "场景id:" + sceneVoId + "未查到有效的地图");
                }
                MultiSimulationSceneCarParam sceneCarParam = new MultiSimulationSceneCarParam();
                sceneCarParam.setSceneId(sceneVoId);
                sceneCarParam.setMapId(mapId);
                List<MultiSimulationSceneCarVO> multiSimulationSceneCarVOS = sceneCarMapper.selectSceneCarList(sceneCarParam);
                ResponseBodyVO sceneCars = checkAllSceneCars(multiSimulationSceneCarVOS, sceneVoId);
                if (sceneCars.getCode() != ResponseBodyVO.Response.SUCCESS.getCode()){
                    return sceneCars;
                }
            }
            MultiSimulationProjectKafkaParam multiSimulationProjectKafkaParam = buildSendKafkaParam(projectId, projectVO.getProjectMaxSeconds());
            projectRunToKafka(multiSimulationProjectKafkaParam);
            res = multiSimulationProjectMapper.updateMultiSimulationProjectStatus(param);
        } else if (projectStatus == MultiSimulationStatusEnum.COMPLETED_STATUS.getProjectStatus()) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "当前状态已完成,不允许操作");   
        } else if (projectStatus == MultiSimulationStatusEnum.RUN_STATUS.getProjectStatus()) {
            if (status != MultiSimulationStatusEnum.TERMINATED_STATUS.getProjectStatus()){
                return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "当前任务状态不允许执行此操作");
            }
            projectStopMultiKafka(projectId);
            res = multiSimulationProjectMapper.updateMultiSimulationProjectStatus(param);
        }
        if (res > 0){
            return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE);
    }

    public MultiSimulationProjectKafkaParam buildSendKafkaParam(String projectId, Integer defaultTime){
        MultiSimulationProjectKafkaParam multiSimulationProjectKafkaParam = new MultiSimulationProjectKafkaParam();
        multiSimulationProjectKafkaParam.setProjectId(projectId);
        MultiSimulationSceneParam sceneParam = new MultiSimulationSceneParam();
        sceneParam.setProjectId(projectId);
        List<MultiSimulationSceneVO> multiSimulationSceneVOS = simulationSceneMapper.selectSceneList(sceneParam);
        List<MultiSimulationSceneKafkaParam> sceneKafkaParamList = new ArrayList<>();
        for (MultiSimulationSceneVO scene : multiSimulationSceneVOS) {
            String id = scene.getId();
            MultiSimulationSceneKafkaParam multiSimulationSceneKafkaParam = new MultiSimulationSceneKafkaParam();
            multiSimulationSceneKafkaParam.setMapId(scene.getMapId());
            multiSimulationSceneKafkaParam.setProjectId(scene.getProjectId());
            // 设置场景id
            multiSimulationSceneKafkaParam.setId(id);
            MultiSimulationSceneCarParam sceneCarParam = new MultiSimulationSceneCarParam();
            sceneCarParam.setSceneId(id);
            List<MultiSimulationSceneCarVO> multiSimulationSceneCarVOS = sceneCarMapper.selectSceneCarList(sceneCarParam);
            multiSimulationSceneKafkaParam.setSimulationSceneCarVOList(multiSimulationSceneCarVOS);
            sceneKafkaParamList.add(multiSimulationSceneKafkaParam);
        }
        multiSimulationProjectKafkaParam.setKafkaParamList(sceneKafkaParamList);
        multiSimulationProjectKafkaParam.setDefaultTime(defaultTime);
        return multiSimulationProjectKafkaParam;
    }

    @SneakyThrows
    private void projectRunToKafka(MultiSimulationProjectKafkaParam param) {
        KafkaParameter kafkaParameter = new KafkaParameter();
        kafkaParameter.setTopic(ProjectConstants.RUN_MULTI_TOPIC);
        String data = JsonUtil.beanToJson(param);
        kafkaParameter.setData(data);
        log.info("推送项目运行消息到 Kafka：" + data);
        sendKafka(kafkaParameter);
    }
    @SneakyThrows
    private void projectStopMultiKafka(String projectId) {
        KafkaParameter kafkaParameter = new KafkaParameter();
        kafkaParameter.setTopic(ProjectConstants.STOP_MULTI_TOPIC);
        JSONObject object = new JSONObject();
        object.put("projectId", projectId);
        kafkaParameter.setData(object.toJSONString());
        log.info("停止任务推送项目运行消息到 Kafka：" + object.toJSONString());
        sendKafka(kafkaParameter);
    }

    // TODO 测试时候打开
    public void sendKafka(KafkaParameter kafkaParameter){
        kafkaTemplate.send(kafkaParameter.getTopic(), kafkaParameter.getData()).addCallback(success -> {
            // 消息发送到的topic
            String topic = success.getRecordMetadata().topic();
            // 消息发送到的分区
            int partition = success.getRecordMetadata().partition();
            // 消息在分区内的offset
            long offset = success.getRecordMetadata().offset();
            log.info("停止任务发送消息成功，主题 topic 为：" + topic + "，分区 partition 为：" + partition + "，偏移量为：" + offset + "，消息体为：" + kafkaParameter.getData());
        }, failure -> log.error("发送消息失败:" + failure.getMessage()));
    }

    public ResponseBodyVO<MultiSimulationProjectVO> submitMultiSimulationProjectDetail(MultiSimulationProjectParam param){
        String currentUserId = AuthUtil.getCurrentUserId();
        param.setProjectUserId(currentUserId);
        // 先更新
        multiSimulationProjectMapper.updateMultiSimulationProject(param);
        Integer status = param.getProjectStatus();
        if (status != MultiSimulationStatusEnum.INIT_STATUS.getProjectStatus()){
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "当前任务状态不允许执行此操作");
        }
        ResponseBodyVO responseBodyVO = updateMultiSimulationProjectStatus(param);
        if (responseBodyVO.getCode() != ResponseBodyVO.Response.SUCCESS.getCode()){
            return responseBodyVO;
        }
        MultiSimulationProjectVO build = MultiSimulationProjectVO.builder().projectId(param.getProjectId()).projectStatus(MultiSimulationStatusEnum.RUN_STATUS.getProjectStatus())
            .projectStatusValue(MultiSimulationStatusEnum.RUN_STATUS.getProjectStatusValue()).build();
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, build);
    }

    @Override
    @SneakyThrows
    public ResponseBodyVO<String> updateMultiSimulationProject(MultiSimulationProjectParam param) {
        if (StringUtils.isBlank(param.getProjectId())) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "项目id不能为空");
        }
        String currentUserId = AuthUtil.getCurrentUserId();

        param.setProjectName(StringUtils.isBlank(param.getProjectName()) ? "" : param.getProjectName());
        param.setProjectDescription(StringUtils.isBlank(param.getProjectDescription()) ? "" : param.getProjectDescription());
        param.setProjectMaxSeconds(Objects.isNull(param.getProjectMaxSeconds()) ? 0 : param.getProjectMaxSeconds());
        param.setProjectUserId(currentUserId);
        int i = multiSimulationProjectMapper.updateMultiSimulationProject(param);
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, null);
    }

    @Override
    @SneakyThrows
    public ResponseBodyVO<MultiSimulationProjectVO> getMultiSimulationProjectDetail(MultiSimulationProjectParam param) {
        if (StringUtils.isBlank(param.getProjectId())) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "项目id不能为空");
        }
        MultiSimulationProjectVO multiSimulationProjectVO = multiSimulationProjectMapper.selectMultiSimulationProjectById(param.getProjectId());
        if (Objects.isNull(multiSimulationProjectVO)) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "未查询出有效的项目");
        }
        multiSimulationProjectVO.setProjectStatusValue(MultiSimulationStatusEnum.matchStatusEnumByStatus(multiSimulationProjectVO.getProjectStatus()).getProjectStatusValue());
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, multiSimulationProjectVO);
    }

    @Override
    @SneakyThrows
    public ResponseBodyVO<MultiSimulationSceneVO> addMultiSimulationScene(MultiSimulationSceneParam param) {
        if (StringUtils.isBlank(param.getProjectId())) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "项目id不能为空");
        }
        MultiSimulationScenePO build = MultiSimulationScenePO.builder().id(StringUtil.getRandomUUID()).projectId(param.getProjectId()).build();
        int i = simulationSceneMapper.addMultiSimulationScene(build);
        if (i > 0) {
            MultiSimulationSceneVO sceneVO = MultiSimulationSceneVO.builder().sceneId(build.getId()).build();
            return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, sceneVO);
        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SERVER_FAILURE);
    }


    @Override
    @SneakyThrows
    public ResponseBodyVO deleteMultiSimulationScene(MultiSimulationSceneParam param) {
        if (StringUtils.isBlank(param.getSceneId())) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "删除失败,场景id不能为空");
        }
        int i = simulationSceneMapper.deleteMultiSimulationScene(param);
        if (i > 0) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, "删除成功");
        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE);
    }

    @Override
    @SneakyThrows
    public ResponseBodyVO<PageInfo<MultiSimulationSceneVO>> selectMultiSimulationSceneList(MultiSimulationSceneParam param) {
        if (StringUtils.isBlank(param.getProjectId())) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "查询失败,id为空");
        }
        String projectId = param.getProjectId();
        MultiSimulationProjectVO projectVO = multiSimulationProjectMapper.selectMultiSimulationProjectById(projectId);
        Integer status = projectVO.getProjectStatus();
        boolean isNeedStatus = status == MultiSimulationStatusEnum.INIT_STATUS.getProjectStatus() ? false : true;
        Map<String, Integer> sceneIdStatusMap = new HashMap<>();
        if (isNeedStatus){
            List<MultiSimulationProjectTaskRecordPO> recordPOList = taskRecordMapper.selectMultiSimulationProjectTaskRecordList(projectId);
            if (!CollectionUtils.isEmpty(recordPOList)){
                for (MultiSimulationProjectTaskRecordPO taskRecord: recordPOList) {
                    sceneIdStatusMap.put(taskRecord.getSceneId(), taskRecord.getStatus());
                }
            }
        }
        if (Objects.isNull(param.getPageNum())) {
            param.setPageNum(1);
        }
        if (Objects.isNull(param.getPageSize())) {
            param.setPageSize(10);
        }
        setPage(param.getPageNum(), param.getPageSize());
        List<MultiSimulationSceneVO> multiSimulationSceneVOS = simulationSceneMapper.selectSceneList(param);
//        PageHelper.clearPage();
        if (!CollectionUtils.isEmpty(multiSimulationSceneVOS)) {
            for (MultiSimulationSceneVO scene : multiSimulationSceneVOS) {
                String sceneId = scene.getSceneId();
                int i = sceneCarMapper.selectSceneCarNumsBySceneId(sceneId);
                scene.setCarNums(i);
                String mapId = scene.getMapId();
                if (StringUtils.isBlank(mapId)) {
                    continue;
                }
                SimulationMapVO simulationMapVO = mapMapper.selectMapByMapId(mapId);
                if (Objects.isNull(simulationMapVO)) {
                    continue;
                }
                scene.setMapName(simulationMapVO.getMapName());
                if (isNeedStatus){
                    scene.setTaskStatus(sceneIdStatusMap.get(sceneId));
                }
            }
        }
        PageInfo<MultiSimulationSceneVO> pageInfo = new PageInfo<>(multiSimulationSceneVOS);
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, pageInfo);
    }

    @Override
    @SneakyThrows
    public ResponseBodyVO<MultiSimulationSceneVO> getMultiSimulationSceneDetail(MultiSimulationSceneParam param) {
        if (StringUtils.isBlank(param.getSceneId())) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "查询失败,场景id为空");
        }
        MultiSimulationSceneVO sceneVO = simulationSceneMapper.selectSceneDetailBySceneId(param.getSceneId());
        if (Objects.isNull(sceneVO)) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "查询失败,未找到有效的场景");
        }
        String mapId = sceneVO.getMapId();
        if (StringUtils.isNotBlank(mapId)) {
            SimulationMapVO simulationMapVO = mapMapper.selectMapByMapId(mapId);
            if (Objects.isNull(simulationMapVO)) {
                sceneVO.setMapId("");
            } else {
                sceneVO.setMapName(simulationMapVO.getMapName());
                sceneVO.setMapImgUrl(simulationMapVO.getMapImgUrl());
            }
        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, sceneVO);
    }

    @Override
    @SneakyThrows
    public ResponseBodyVO<PageInfo<MultiSimulationSceneCarVO>> getMultiSimulationSceneCarList(MultiSimulationSceneCarParam param) {
        String sceneId = param.getSceneId();
        if (StringUtils.isBlank(sceneId)) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "查询失败,场景id为空");
        }
        if (Objects.isNull(param.getPageNum())) {
            param.setPageNum(1);
        }
        if (Objects.isNull(param.getPageSize())) {
            param.setPageSize(10);
        }
        if (StringUtils.isBlank(param.getMapId())){
            PageInfo<MultiSimulationSceneCarVO> pageInfo = new PageInfo<>(new ArrayList<>());
            return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, pageInfo);
//            MultiSimulationSceneVO sceneVO = simulationSceneMapper.selectSceneDetailBySceneId(sceneId);
//            String mapId = sceneVO.getMapId();
//            if (StringUtils.isBlank(mapId)){
//
//            }else {
//                param.setMapId(mapId);
//            }
        }else {
            param.setMapId(param.getMapId());
        }
        setPage(param.getPageNum(), param.getPageSize());
        List<MultiSimulationSceneCarVO> multiSimulationSceneCarVOS = sceneCarMapper.selectSceneCarList(param);
        if (!CollectionUtils.isEmpty(multiSimulationSceneCarVOS)) {
            for (MultiSimulationSceneCarVO car : multiSimulationSceneCarVOS) {
                String algorithmId = car.getAlgorithmId();
                String carId = car.getCarId();
                if (StringUtils.isNotBlank(carId)) {
                    ConfigPO configPO = simulationManualProjectMapper.selectConfigVehicleById(carId);
                    if (!Objects.isNull(configPO)) {
                        car.setCarName(configPO.getConfigName());
                    } else {
                        log.info("根据carId未查出有效的车辆信息carId:{}", carId);
                        car.setCarId("");
                    }
                }
                if (StringUtils.isNotBlank(algorithmId)) {
                    AlgorithmPO algorithmPO = simulationManualProjectMapper.selectAvailableAlgorithmById(algorithmId);
                    if (!Objects.isNull(algorithmPO)) {
                        car.setAlgorithmName(algorithmPO.getAlgorithmName());
                    } else {
                        log.info("根据算法id未查出有效的算法信息algorithmId:{}", algorithmId);
                        car.setAlgorithmId("");
                    }
                }
                String pathStart = car.getPathStart();
                car.setPathStartJson(JSONObject.parseObject(pathStart));
                String pathEnd = car.getPathEnd();
                car.setPathEndJson(JSONObject.parseObject(pathEnd));
                String pathId = car.getPathId();
                if (StringUtils.isNotBlank(pathId)){
                    SimulationMapPathVO simulationMapPathVO = mapPathMapper.selectSimulationMapById(pathId);
                    if (simulationMapPathVO != null){
                        car.setPathSort(simulationMapPathVO.getPathSort());
                    }
                }
            }
        }
        PageInfo<MultiSimulationSceneCarVO> pageInfo = new PageInfo<>(multiSimulationSceneCarVOS);
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, pageInfo);
    }

    public ResponseBodyVO deleteMultiSimulationSceneCar(MultiSimulationSceneCarParam param) {
        int i = sceneCarMapper.deleteMultiSimulationSceneCar(param);
        if (i > 0) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
        }
        MultiSimulationSceneCarVO multiSimulationSceneCarVO = sceneCarMapper.selectSceneCarById(param);
        if (Objects.isNull(multiSimulationSceneCarVO)) {
            log.info("该id未查出有效的场景车辆信息:{}", param.getSceneCarId());
            return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE);
    }

    public ResponseBodyVO<MultiSimulationSceneCarVO> addOrUpdateMultiSimulationSceneCar(MultiSimulationSceneCarParam param) {

        String mapId = param.getMapId();
        if (StringUtils.isBlank(mapId)){
            String pathId = param.getPathId();
            if (StringUtils.isBlank(pathId)){
                return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "地图id为空");
            }else {
                SimulationMapPathVO simulationMapPathVO = mapPathMapper.selectSimulationMapById(pathId);
                if (simulationMapPathVO == null){
                    return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "地图id为空");
                }
                param.setMapId(mapId);
            }
        }
        param.setCarId(StringUtils.isBlank(param.getCarId()) ? "" : param.getCarId());
        param.setAlgorithmId(StringUtils.isBlank(param.getAlgorithmId()) ? "" : param.getAlgorithmId());
        param.setPathId(StringUtils.isBlank(param.getPathId()) ? "" : param.getPathId());
        param.setPathStart(param.getPathStart()== null ? new JSONObject() : param.getPathStart());
        param.setPathEnd(param.getPathEnd() == null ? new JSONObject() : param.getPathEnd());
//        param.setPathStartPoint(StringUtils.isBlank(param.getPathStartPoint()) ? "" : param.getPathStartPoint());
//        param.setPathEndPoint(StringUtils.isBlank(param.getPathEndPoint()) ? "" : param.getPathEndPoint());
        param.setCarSort(Objects.isNull(param.getCarSort()) ? 0 : param.getCarSort());
        param.setAlgorithmType(param.getAlgorithmType() == null ? 0 : param.getAlgorithmType());
        param.setPathStartStr(param.getPathStart().toJSONString());
        param.setPathEndStr(param.getPathEnd().toJSONString());
        if (StringUtils.isBlank(param.getSceneCarId())) {
            param.setSceneCarId(StringUtil.getRandomUUID());
            if (StringUtils.isBlank(param.getSceneId())) {
                return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "场景id为空");
            }
            // 新增时默认不是仿真视角
            param.setIsSimulationCar(0);
            int i = sceneCarMapper.addMultiSimulationSceneCar(param);
            if (i > 0) {
                return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, MultiSimulationSceneCarVO.builder().sceneCarId(param.getSceneCarId()).build());
            }
        } else {
            int i = sceneCarMapper.updateMultiSimulationSceneCar(param);
//            if (i > 0) {
//                return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, MultiSimulationSceneCarVO.builder().sceneCarId(param.getSceneCarId()).build());
//            }
            return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, MultiSimulationSceneCarVO.builder().sceneCarId(param.getSceneCarId()).build());
        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE);
    }

    @Transactional
    public ResponseBodyVO<List<MultiSimulationSceneCarVO>> addOrUpdateMultiSimulationSceneCarList(AddOrUpdateMultiSimulationSceneCarParam sceneCarParam) {
        String mapId = sceneCarParam.getMapId();
        List<MultiSimulationSceneCarParam> paramList = sceneCarParam.getParamList();
        if (CollectionUtils.isEmpty(paramList) || StringUtils.isBlank(sceneCarParam.getMapId())) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "数据为空");
        }
        MultiSimulationSceneVO sceneVO = simulationSceneMapper.selectSceneDetailBySceneId(sceneCarParam.getSceneId());
        if (Objects.isNull(sceneVO)){
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "未查询到场景");
        }
        for (MultiSimulationSceneCarParam param : paramList) {
            if (StringUtils.isNotBlank(param.getSceneCarId())) {
                MultiSimulationSceneCarVO multiSimulationSceneCarVO = sceneCarMapper.selectSceneCarById(param);
                if (Objects.isNull(multiSimulationSceneCarVO)) {
                    return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "存在无效的车辆id");
                }
            }
        }
        List<MultiSimulationSceneCarVO> ids = new ArrayList<>();
        for (MultiSimulationSceneCarParam param : paramList) {
            param.setMapId(mapId);
            ResponseBodyVO<MultiSimulationSceneCarVO> responseBodyVO = addOrUpdateMultiSimulationSceneCar(param);
            if (responseBodyVO.getCode() != 200) {
                throw new RuntimeException("操作失败");
            }
            ids.add(responseBodyVO.getInfo());
        }
        String oldMapId = sceneVO.getMapId();
        if (!StringUtils.equals(oldMapId, sceneCarParam.getMapId())){
            int i = simulationSceneMapper.updateMultiSimulationSceneMapId(sceneCarParam.getMapId(), sceneCarParam.getSceneId());
            if (i <= 0){
                throw new RuntimeException("操作失败");
            }
        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, ids);
    }

    public ResponseBodyVO setMultiSimulationSceneCarView(MultiSimulationSceneCarParam param) {
        if (StringUtils.isBlank(param.getSceneCarId())) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "参数为空");
        }
        MultiSimulationSceneCarVO multiSimulationSceneCarVO = sceneCarMapper.selectSceneCarById(param);
        if (Objects.isNull(multiSimulationSceneCarVO)) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "未找到有效的车辆配置");
        }
        String sceneId = multiSimulationSceneCarVO.getSceneId();
        if (StringUtils.isBlank(sceneId)) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "未找到对应的场景");
        }
        param.setSceneId(sceneId);
        List<MultiSimulationSceneCarVO> multiSimulationSceneCarVOS = sceneCarMapper.selectSceneCarList(param);
        boolean isLast = false;
        for (MultiSimulationSceneCarVO car : multiSimulationSceneCarVOS) {
            Integer isSimulationCar = car.getIsSimulationCar();
            if (isSimulationCar == 1){
                if (!StringUtils.equals(car.getId(), param.getSceneCarId())){
                    sceneCarMapper.updateMultiSimulationSceneCarView(car.getId(), 0);
                } else {
                    isLast = true;
                }
            }
        }
        if (!isLast){
            int i = sceneCarMapper.updateMultiSimulationSceneCarView(param.getSceneCarId(), 1);
            if (i <= 0) {
                return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE);
            }
        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
    }

    @Override
    @Transactional
    public ResponseBodyVO<MultiSimulationProjectVO> saveAsMultiSimulationProjectDetail(MultiSimulationProjectParam param) {
        String oldProjectId = param.getProjectId();
        MultiSimulationProjectVO projectVO = multiSimulationProjectMapper.selectMultiSimulationProjectById(oldProjectId);
        if (Objects.isNull(projectVO)) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "请先保存当前的多模式仿真任务");
        }
        MultiSimulationProjectParam multiSimulationProjectParam = buildProjectParam(projectVO);
        multiSimulationProjectParam.setProjectName(param.getProjectNewName());

        String newProjectId = multiSimulationProjectParam.getProjectId();
        ResponseBodyVO<MultiSimulationProjectDetailVO> responseBodyVO = addMultiSimulationProject(multiSimulationProjectParam);
        log.info("插入仿真任务主表返回结果:{}", JSONObject.toJSONString(responseBodyVO));
        if (responseBodyVO.getCode() != ResponseBodyVO.Response.SUCCESS.getCode()) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE);
        }
        // 返回的数据
        MultiSimulationProjectVO build = MultiSimulationProjectVO.builder().projectId(multiSimulationProjectParam.getProjectId()).build();
        ResponseBodyVO<MultiSimulationProjectVO> multiSimulationProjectVOResponseBodyVO = new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, build);

        MultiSimulationSceneParam multiSimulationSceneParam = new MultiSimulationSceneParam();
        multiSimulationSceneParam.setProjectId(oldProjectId);
        List<MultiSimulationSceneVO> multiSimulationSceneVOS = simulationSceneMapper.selectSceneList(multiSimulationSceneParam);
        if (CollectionUtils.isEmpty(multiSimulationSceneVOS)) {
            return multiSimulationProjectVOResponseBodyVO;
        }
        for (MultiSimulationSceneVO sceneVO : multiSimulationSceneVOS) {
            MultiSimulationScenePO multiSimulationScenePO = buildScenePO(sceneVO, newProjectId);
            int i = simulationSceneMapper.addMultiSimulationSceneAll(multiSimulationScenePO);
            if (i > 0) {
                // 新的场景id
                String id = multiSimulationScenePO.getId();
                // 使用旧id查询列表
                MultiSimulationSceneCarParam multiSimulationSceneCarParam = new MultiSimulationSceneCarParam();
                multiSimulationSceneCarParam.setSceneId(sceneVO.getId());
                List<MultiSimulationSceneCarVO> multiSimulationSceneCarVOS = sceneCarMapper.selectSceneCarList(multiSimulationSceneCarParam);
                if (!CollectionUtils.isEmpty(multiSimulationSceneCarVOS)) {
                    for (MultiSimulationSceneCarVO car : multiSimulationSceneCarVOS) {
                        MultiSimulationSceneCarParam carParam = buildSceneCarParam(car, id);
                        int add = sceneCarMapper.addMultiSimulationSceneCar(carParam);
                        if (add <= 0) {
                            throw new RuntimeException("新增车辆信息失败");
                        }
                    }
                }
            } else {
                throw new RuntimeException("新增场景失败");
            }
        }
        return multiSimulationProjectVOResponseBodyVO;
    }

    public ResponseBodyVO<MultiSimulationSceneVO> copyMultiSimulationScene(MultiSimulationSceneParam param) {
        if (StringUtils.isBlank(param.getSceneId())) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "参数异常");
        }
        MultiSimulationSceneVO sceneVO = simulationSceneMapper.selectSceneDetailBySceneId(param.getSceneId());
        ResponseBodyVO responseBodyVO = checkScene(sceneVO);
        if (responseBodyVO.getCode() != ResponseBodyVO.Response.SUCCESS.getCode()) {
            return responseBodyVO;
        }
        MultiSimulationSceneCarParam multiSimulationSceneCarParam = new MultiSimulationSceneCarParam();
        multiSimulationSceneCarParam.setSceneId(param.getSceneId());
        List<MultiSimulationSceneCarVO> multiSimulationSceneCarVOS = sceneCarMapper.selectSceneCarList(multiSimulationSceneCarParam);
        ResponseBodyVO sceneCars = checkAllSceneCars(multiSimulationSceneCarVOS, param.getSceneId());
        if (sceneCars.getCode() != ResponseBodyVO.Response.SUCCESS.getCode()) {
            return sceneCars;
        }
        // 插入场景
        MultiSimulationScenePO multiSimulationScenePO = buildScenePO(sceneVO, sceneVO.getProjectId());
        int i = simulationSceneMapper.addMultiSimulationSceneAll(multiSimulationScenePO);
        if (i <= 0) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "新增失败,请检查参数");
        }
        String sceneNewId = multiSimulationScenePO.getId();
        for (MultiSimulationSceneCarVO carVO : multiSimulationSceneCarVOS) {
            MultiSimulationSceneCarParam sceneCarParam = buildSceneCarParam(carVO, sceneNewId);
            int sceneCarRes = sceneCarMapper.addMultiSimulationSceneCar(sceneCarParam);
            if (sceneCarRes <= 0) {
                throw new RuntimeException("新增车辆失败");
            }
        }
        MultiSimulationSceneVO build = MultiSimulationSceneVO.builder().sceneId(sceneNewId).build();
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, build);
    }

    public ResponseBodyVO<MultiSimulationSceneResultVO> viewMultiSimulationProjectResult(MultiSimulationSceneParam param) {
        MultiSimulationSceneVO sceneVO = simulationSceneMapper.selectSceneDetailBySceneId(param.getSceneId());
        if (Objects.isNull(sceneVO)) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "未查到有效的场景记录");
        }
        String projectId = sceneVO.getProjectId();
        MultiSimulationProjectVO projectVO = multiSimulationProjectMapper.selectMultiSimulationProjectById(projectId);
        if (Objects.isNull(projectVO)) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "多模式仿真任务未找到");
        }
        Integer projectStatus = projectVO.getProjectStatus();
        if (projectStatus != MultiSimulationStatusEnum.COMPLETED_STATUS.getProjectStatus()) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "任务不是已完成状态");
        }
        List<MultiSimulationProjectResultVO> collisionDetail = new ArrayList<>();

        List<MultiSimulationProjectResultVO> abnormalParkingDetail = new ArrayList<>();

        List<MultiSimulationProjectResultVO> outOfPavementDetail = new ArrayList<>();
        MultiSimulationProjectResultParam resultParam = new MultiSimulationProjectResultParam();
        resultParam.setSceneId(param.getSceneId());
        List<MultiSimulationProjectResultVO> multiSimulationProjectResultVOS = resultMapper.selectProjectResultList(resultParam);
        String phrases = null;
        if (!CollectionUtils.isEmpty(multiSimulationProjectResultVOS)) {
            for (MultiSimulationProjectResultVO result : multiSimulationProjectResultVOS) {
                Integer abnormalType = result.getAbnormalType();
//                String abnormalTime = result.getAbnormalTime();
//                String s = TimeUtil.changeTimeFormat(abnormalTime);
//                result.setAbnormalTimeDescription(abnormalTime);
                if (abnormalType == MultiSimulationResultTypeEnum.COLLISION.getResultType()){
                    collisionDetail.add(result);
                } else if (abnormalType == MultiSimulationResultTypeEnum.ABNORMAL_PARKING.getResultType()) {
                    abnormalParkingDetail.add(result);
                } else if (abnormalType == MultiSimulationResultTypeEnum.OUT_OF_PAVEMENT.getResultType()) {
                    outOfPavementDetail.add(result);
                }else if (abnormalType == MultiSimulationResultTypeEnum.LAST_DESCRIPTION.getResultType()){
                    phrases = result.getAbnormalTimeDescription();
                }
            }
        }
        MultiSimulationSceneResultVO multiSimulationSceneResultVO = new MultiSimulationSceneResultVO();
        multiSimulationSceneResultVO.setId(param.getSceneId()).setProjectId(sceneVO.getProjectId()).setProjectResultSimulationUrl(sceneVO.getProjectResultSimulationUrl())
            .setProjectResultOverallUrl(sceneVO.getProjectResultOverallUrl()).setSceneName(sceneVO.getSceneName())
            .setPhrases(phrases)
//            .setCollisionTimes(collisionDetail.size())
//            .setAbnormalParkingTimes(abnormalParkingDetail.size()).setOutOfPavementTimes(outOfPavementDetail.size())
            .setCollisionDetail(collisionDetail).setAbnormalParkingDetail(abnormalParkingDetail).setOutOfPavementDetail(outOfPavementDetail);
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, multiSimulationSceneResultVO);
    }


    public ResponseBodyVO checkAllScene(List<MultiSimulationSceneVO> sceneVOList) {
        if (CollectionUtils.isEmpty(sceneVOList)) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "有效场景为空");
        }
        for (MultiSimulationSceneVO scene : sceneVOList) {
            ResponseBodyVO responseBodyVO = checkScene(scene);
            if (responseBodyVO.getCode() != ResponseBodyVO.Response.SUCCESS.getCode()) {
                return responseBodyVO;
            }
        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
    }

    public ResponseBodyVO checkScene(MultiSimulationSceneVO sceneVO) {
        if (Objects.isNull(sceneVO)) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "未查出有效的场景");
        }
        String mapId = sceneVO.getMapId();
        if (StringUtils.isBlank(mapId)) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "原始场景未配置地图");
        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
    }

    public ResponseBodyVO checkAllSceneCars(List<MultiSimulationSceneCarVO> multiSimulationSceneCarVOS, String sceneId) {
        if (CollectionUtils.isEmpty(multiSimulationSceneCarVOS)) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "场景id:" + sceneId + "场景未查出有效的车辆");
        }
        for (MultiSimulationSceneCarVO carVo : multiSimulationSceneCarVOS) {
            ResponseBodyVO responseBodyVO = checkSceneCar(carVo);
            if (responseBodyVO.getCode() != ResponseBodyVO.Response.SUCCESS.getCode()) {
                return responseBodyVO;
            }
        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
    }

    //TODO 待校验详细的车辆算法
    public ResponseBodyVO checkSceneCar(MultiSimulationSceneCarVO carVO) {
        if (StringUtils.isBlank(carVO.getCarId())) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "车辆id:" + carVO.getId() + "未配置车辆");
        }
        if (StringUtils.isBlank(carVO.getAlgorithmId())) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "车辆id:" + carVO.getId() + "未配置算法");
        }
        if (StringUtils.isBlank(carVO.getPathId())) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "车辆id:" + carVO.getId() + "未配置轨迹");
        }
        if (StringUtils.isBlank(carVO.getPathStart())) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "车辆id:" + carVO.getId() + "未配置轨迹起点");
        }
        if (StringUtils.isBlank(carVO.getPathEnd())) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "车辆id:" + carVO.getId() + "未配置轨迹终点");
        }
//        if (StringUtils.isBlank(carVO.getPathStartPoint())) {
//            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "车辆id:" + carVO.getId() + "未配置轨迹起点朝向");
//        }
//        if (StringUtils.isBlank(carVO.getPathEndPoint())) {
//            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "车辆id:" + carVO.getId() + "未配置轨迹终点朝向");
//        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
    }

    @SneakyThrows
    public void exportProjectTaskFileById(MultiSimulationProjectParam param){
        String projectId = param.getProjectId();
        if (StringUtils.isBlank(projectId)){
            log.info("下载多模式仿真结果失败,projectId为空");
            return;
        }
        MultiSimulationProjectVO projectVO = multiSimulationProjectMapper.selectMultiSimulationProjectById(projectId);
        if (Objects.isNull(projectVO)){
            log.info("下载多模式仿真结果失败,查询出仿真结果为空projectId:{}", projectId);
            return;
        }
        Integer status = projectVO.getProjectStatus();
        if (status != MultiSimulationStatusEnum.COMPLETED_STATUS.getProjectStatus()){
            log.info("下载多模式仿真结果失败,当前任务状态非完成状态projectId:{}", projectId);
            return;
        }
        List<MultiSimulationProjectTaskRecordPO> recordPOList = taskRecordMapper.selectMultiSimulationProjectTaskRecordList(projectId);
        if (CollectionUtils.isEmpty(recordPOList)){
            log.info("下载多模式仿真结果失败,当前任务结果为空:{}", projectId);
            return;
        }
        List<MultiSimulationProjectTaskRecordPO> list = new ArrayList<>();
        for (MultiSimulationProjectTaskRecordPO record: recordPOList) {
            Integer recordStatus = record.getStatus();
            if (recordStatus == MultiSimulationTaskStatusEnum.INIT_STATUS.getProjectStatus() || recordStatus == MultiSimulationTaskStatusEnum.RUN_STATUS.getProjectStatus()){
                log.info("下载多模式仿真结果失败,当前任务存在未完成的任务projectId:{},taskId:{}", projectId, record.getId());
                continue;
            }
            list.add(record);
        }
        ZipOutputStream zos = null;
        try {
            HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
            response.setContentType("multipart/form-data");
            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode("运行任务包.zip", "UTF-8"));
            zos = new ZipOutputStream(response.getOutputStream());
            int len;
            byte[] buffer = new byte[1024];
            for (MultiSimulationProjectTaskRecordPO task: list) {
                String taskBody = task.getTaskBody();
                JSONObject jsonObject = JSONObject.parseObject(taskBody);
                String string = jsonObject.getJSONObject("info").getString("task_path");
                MinioParameter minioParameter = new MinioParameter();
                minioParameter.setObjectName(string);
                ResponseBodyVO<List<String>> list1 = fileDownService.list(minioParameter);
                List<String> info = list1.getInfo();
                for (String s: info) {
                    String fileName = null;
                    String zipPath = null;
                    if (s.contains("/")) {
                        fileName = s.substring(s.lastIndexOf("/") + 1);
                    }else {
                        fileName = s.substring(s.lastIndexOf("\\") + 1);
                    }
                    zipPath = multiDownloadTaskTempPath + projectId + File.separator + task.getId() + File.separator + fileName;
                    String substring = s.substring(s.lastIndexOf(".") + 1);
                    if (StringUtils.equals(substring, "mp4")){
                        MinioParameter minioPar = new MinioParameter();
                        minioPar.setObjectName(s);
                        Response down = fileDownService.download(minioPar);
                        Response.Body body = down.body();
                        ZipEntry entry2 = new ZipEntry(zipPath);
                        zos.putNextEntry(entry2);
                        BufferedInputStream in = new BufferedInputStream(body.asInputStream());
                        while ((len = in.read(buffer)) != -1) {
                            zos.write(buffer, 0, len);
                        }
                        in.close();
                    }else if ("Ego.csv".equals(fileName) || "evaluation.csv".equals(fileName)) {
                        MinioParameter minioPar = new MinioParameter();
                        minioPar.setObjectName(s);
                        Response down = fileDownService.download(minioPar);
                        Response.Body body = down.body();
                        // 任务文件路径
                        ZipEntry entry = new ZipEntry(zipPath);
                        zos.putNextEntry(entry);
                        BufferedInputStream in = new BufferedInputStream(body.asInputStream());
                        while ((len = in.read(buffer)) != -1) {
                            zos.write(buffer, 0, len);
                        }
                        in.close();
                    }
                }
            }
        }catch (Exception e){
            log.info("下载失败", e);
        }finally {
            try {
                if (zos != null) {
                    zos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public static MultiSimulationScenePO buildScenePO(MultiSimulationSceneVO sceneVO, String projectId) {
        MultiSimulationScenePO build = MultiSimulationScenePO.builder()
            .projectId(projectId).sceneName(sceneVO.getSceneName()).id(StringUtil.getRandomUUID())
            .mapId(sceneVO.getMapId())
            .build();
        return build;
    }

    public static MultiSimulationProjectParam buildProjectParam(MultiSimulationProjectVO projectVO) {
        MultiSimulationProjectParam multiSimulationProjectParam = new MultiSimulationProjectParam();
        multiSimulationProjectParam.setProjectId(StringUtil.getRandomUUID()).setProjectKey(projectVO.getProjectKey())
            .setProjectDescription(projectVO.getProjectDescription()).setProjectMaxSeconds(projectVO.getProjectMaxSeconds())
            .setProjectStatus(MultiSimulationStatusEnum.INIT_STATUS.getProjectStatus());
        return multiSimulationProjectParam;
    }

    public static MultiSimulationSceneCarParam buildSceneCarParam(MultiSimulationSceneCarVO carVO, String newSceneId) {
        String pathStart = carVO.getPathStart();
        JSONObject objectStart = JSONObject.parseObject(pathStart);
        String pathEnd = carVO.getPathEnd();
        JSONObject objectEnd = JSONObject.parseObject(pathEnd);
        MultiSimulationSceneCarParam multiSimulationSceneCarParam = new MultiSimulationSceneCarParam();
        multiSimulationSceneCarParam.setSceneCarId(carVO.getId()).setSceneId(newSceneId)
            .setCarId(carVO.getCarId()).setAlgorithmId(carVO.getAlgorithmId())
            .setMapId(carVO.getMapId())
            .setPathId(carVO.getPathId())
            .setPathStart(objectStart).setPathEnd(objectEnd)
            .setPathStartStr(pathStart)
            .setPathEndStr(pathEnd)
            .setCarSort(carVO.getCarSort()).setIsSimulationCar(carVO.getIsSimulationCar());
        return multiSimulationSceneCarParam;
    }

    private void setPage(Integer pageNum, Integer pageSize) {
        PageVO pageVO = new PageVO();
        pageVO.setCurrentPage(pageNum);
        pageVO.setPageSize(pageSize);
        PageUtil.setPageInfo(pageVO);
    }
}
