package com.base.track.service;


import com.base.api.client.InstanceRpcService;
import com.base.api.client.SatelliteRpcService;
import com.base.api.client.SatelliteStationMatchRpcService;
import com.base.api.client.StationRpcService;
import com.base.api.model.*;
import com.base.api.model.request.QueryStationAddRpcDTO;
import com.base.orbit.Exception.AssertException;
import com.base.orbit.utils.DateUtils;
import com.base.orbit.utils.TimeUtil;
import com.base.task.cdlatch.aop.Countdlatch;
import com.base.task.cdlatch.aop.model.InstanceAop;
import com.base.task.cdlatch.aop.model.SubPointAop;
import com.base.task.model.Enums.TaskTypeEnum;
import com.base.task.model.Task;
import com.base.task.model.input.EphInput;
import com.base.task.model.input.InstanceInput;
import com.base.task.model.input.StationArcInput;
import com.base.task.model.input.SubPointInput;
import com.base.track.model.dto.response.YxInfoBasisStationDTO;
import com.base.track.model.entity.AstronomicalForecast;
import com.base.track.model.entity.StationBaseBizInfo;
import com.base.track.model.enums.PayloadTypeEnums;
import com.base.track.thread.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class CalService {

    @Resource
    AstronomyThread astronomyThread;
    @Resource
    OrbitNumThread orbitNumThread;
    @Resource
    OrbitNumService orbitNumService;

    @Resource
    TrbutDataService trbutDataService;
    @Resource
    SatelliteStationMatchRpcService satelliteStationMatchDTOService;
    @Resource
    AstronomicalForecastService astronomicalForecastService;


    @Resource
    SatelliteRpcService infoBasisSatelliteRpcService;
    @Resource
    InstanceRpcService infoBasisInstanceRpcService;
    @Resource
    StationRpcService infoBasisStationRpcService;
    @Resource
    SubPointDataService subPointDataService;


    @Resource
    SatelliteRpcService satelliteService;

    @Resource
    InstanceRpcService instanceService;

    @Resource
    StationRpcService stationRpcService;

    /**
     * 结束可执行文件的脚本文件路径
     */
    @Value("${script.fileroute}")
    private String fileroute;

    /**
     * 轨道星历计算
     *
     * @param startTime 计算开始时间
     * @param endTime   计算结束时间
     */


    @Countdlatch(TaskTypeEnum.EPHEMERIS_CALCULATION)
    public List<Task> calcEph(SubPointAop subPointAop) {

        List<String> satelliteCodes = subPointAop.getSatelliteCodes();
        List<Task> tasks = subPointAop.getTasks();
        for (Task task : tasks) {
            String startTime = task.getStartTime();
            String endTime = task.getEndTime();
/*            Date newstart = new Date(DateUtils.StringToDate(startTime).getTime() - 8 * 3600 * 1000);
            Date newend = new Date(DateUtils.StringToDate(endTime).getTime() - 8 * 3600 * 1000);
            startTime = DateUtils.DateToString(newstart);
            endTime = DateUtils.DateToString(newend);*/
            LocalDateTime starDateTime = LocalDateTime.of(DateUtils.string2LocalDateTime(startTime, DateUtils.YYYY_MM_DD_HH_MM_SS).toLocalDate(), LocalTime.MIN);
            startTime = DateUtils.LocalDateTime2String(starDateTime, "yyyy-MM-dd HH:mm:ss");
            List<SatelliteRpcDTO> satelliteRpcDTOList = satelliteService.listByIds(satelliteCodes);

            //轨道信息
            List<InstanceRpcDTO> listBySatelliteCode = instanceService.getListBySatelliteCode(satelliteCodes);
            // 遍历卫星和轨道信息
            String satelliteAndInstance = satelliteCodes.get(0);
            SatelliteRpcDTO satelliteRpcDTO = satelliteRpcDTOList.stream().filter(t -> t.getSatelliteCode().equals(satelliteAndInstance)).collect(Collectors.toList()).get(0);
            EphInput ephInput = new EphInput();
            BeanUtils.copyProperties(satelliteRpcDTO, ephInput);
            ephInput.setStartTime(startTime);
            ephInput.setEndTime(endTime);
            ephInput.setStartTime1(startTime);
            ephInput.setEndTime1(endTime);
            ephInput.setDir(task.getResultDataSavePath());
            ephInput.setEarthGravityFieldModeOrde1(satelliteRpcDTO.getEarthGravityFieldModeOrde1() != null ? satelliteRpcDTO.getEarthGravityFieldModeOrde1() : "32.0");
            ephInput.setEarthGravityFieldModeOrde2(satelliteRpcDTO.getEarthGravityFieldModeOrde2() != null ? satelliteRpcDTO.getEarthGravityFieldModeOrde2() : "32.0");

            List<InstanceRpcDTO> collect = listBySatelliteCode.stream().filter(t -> t.getSatelliteCode().equals(satelliteAndInstance)).collect(Collectors.toList());
            List<InstanceRpcDTO> collect1 = collect.stream().sorted((o1, o2) -> o1.getEpochTime().compareTo(o2.getEpochTime())).collect(Collectors.toList());
            BeanUtils.copyProperties(collect1.get(0), ephInput);
            ephInput.setEpochTime1(TimeUtil.format(new Date(collect1.get(0).getEpochTime().getTime() - 8 * 3600 * 1000)));
            ephInput.setEpochTime2(TimeUtil.format(new Date(collect1.get(0).getEpochTime().getTime() - 8 * 3600 * 1000)));
            String type = ephInput.getLoadType();
            String typestr = String.valueOf(PayloadTypeEnums.valueOf(type).getPayloadType());
            ephInput.setLoadType(typestr);
            task.setInput(ephInput);
        }
        return tasks;

    }

    /**
     * 星下点计算
     *
     * @param 卫星代号集合
     * @param startTime 开始时间
     * @param endTime   结束时间
     */

    @Countdlatch(TaskTypeEnum.SUB_POINT)
    public List<Task> calcSubPoint(SubPointAop subPointAop) {

        List<String> satelliteCodes = subPointAop.getSatelliteCodes();

        List<SatelliteAndInstanceRpcDTO> satelliteAndInstances = groupingData(satelliteCodes);
        List<Task> tasks = subPointAop.getTasks();
        for (Task task : tasks) {
            SubPointInput subPointInput = new SubPointInput();
            String startTime = task.getStartTime();
            String endTime = task.getEndTime();
            Date newstart = new Date(DateUtils.StringToDate(startTime).getTime() - 8 * 3600 * 1000);
            Date newend = new Date(DateUtils.StringToDate(endTime).getTime() - 8 * 3600 * 1000);
            startTime = DateUtils.DateToString(newstart);
            endTime = DateUtils.DateToString(newend);
            subPointInput = getsubPointInput(subPointInput, satelliteAndInstances.get(0), startTime, endTime, task.getResultDataSavePath());
            task.setInput(subPointInput);
        }
        return tasks;
    }

    @Countdlatch(TaskTypeEnum.INSTANCE)
    public List<Task> calcInstance(InstanceAop instanceAop) {

        String satelliteCode = instanceAop.getSatelliteCode();
        List<Task> tasks = instanceAop.getTasks();
        for (Task task : tasks) {
            String startTime = task.getStartTime();
            String endTime = task.getEndTime();

            InstanceInput instanceInput = new InstanceInput();
            instanceInput.setSatelliteCode(satelliteCode);
            instanceInput.setMass(instanceAop.getMass());
            instanceInput.setStartTime(TimeUtil.format(new Date(TimeUtil.strToDate(startTime).getTime() - 8 * 3600 * 1000)));
            instanceInput.setEndTime(TimeUtil.format(new Date(TimeUtil.strToDate(endTime).getTime() - 8 * 3600 * 1000)));

            instanceInput.setStartTime2(TimeUtil.format(new Date(TimeUtil.strToDate(startTime).getTime() - 8 * 3600 * 1000)));
            instanceInput.setEndTime2(TimeUtil.format(new Date(TimeUtil.strToDate(endTime).getTime() - 8 * 3600 * 1000)));


            /*输入历元时刻*/
            instanceInput.setEpochTime1(TimeUtil.format(new Date(TimeUtil.strToDate(instanceAop.getEpochTime()).getTime() - 8 * 3600 * 1000)));
            /*输出历元时刻*/
            instanceInput.setEpochTime2(TimeUtil.format(new Date(TimeUtil.strToDate(startTime).getTime() - 8 * 3600 * 1000)));

            instanceInput.setSemiMajorAxis(instanceAop.getSemiMajorAxis());
            instanceInput.setEccentricity(instanceAop.getEccentricity());
            instanceInput.setInclination(instanceAop.getInclination());
            instanceInput.setRaan(instanceAop.getRaan());
            instanceInput.setArgumentOfPerigee(instanceAop.getArgumentOfPerigee());
            instanceInput.setMeanAnoMaly(instanceAop.getMeanAnoMaly());
            task.setInput(instanceInput);

            task.setSatelliteCode(satelliteCode);
        }
        return tasks;

    }

    private SubPointInput getsubPointInput(SubPointInput subPointInput, SatelliteAndInstanceRpcDTO satelliteAndInstance, String startTime, String endTime, String filePathtest) {
        YxInfoBasisSatelliteRpcDTO infoBasisSatelliteDO = satelliteAndInstance.getYxInfoBasisSatelliteDTO();
        YxInfoBasisInstanceRpcDTO infoBasisInstanceDO = satelliteAndInstance.getYxInfoBasisInstanceDTO();

        BeanUtils.copyProperties(infoBasisInstanceDO, subPointInput);

        subPointInput.setSatelliteCode(infoBasisSatelliteDO.getSatelliteCode());
        subPointInput.setMass(infoBasisSatelliteDO.getMass());
        subPointInput.setWindArea(infoBasisSatelliteDO.getWindArea());
        subPointInput.setShineArea(infoBasisSatelliteDO.getShineArea());
        subPointInput.setEarthGravityFieldModeOrde1(infoBasisSatelliteDO.getEarthGravityFieldModeOrde1() != null ? infoBasisSatelliteDO.getEarthGravityFieldModeOrde1() : "32.0");
        subPointInput.setEarthGravityFieldModeOrde2(infoBasisSatelliteDO.getEarthGravityFieldModeOrde2() != null ? infoBasisSatelliteDO.getEarthGravityFieldModeOrde2() : "32.0");
        subPointInput.setStartTime(startTime);
        subPointInput.setEndTime(endTime);
        subPointInput.setFilePath(filePathtest);
        subPointInput.setStartTime2(startTime);
        subPointInput.setEndTime2(endTime);
        subPointInput.setOrbitNum(infoBasisInstanceDO.getOrbitNum());
        subPointInput.setEpochTime1(TimeUtil.format(new Date(infoBasisInstanceDO.getEpochTime().getTime() - 8 * 3600 * 1000)));
        subPointInput.setEpochTime2(TimeUtil.format(new Date(infoBasisInstanceDO.getEpochTime().getTime() - 8 * 3600 * 1000)));
        return subPointInput;
    }

    /**
     * 进出站计算
     *
     * @param satelliteIdList 卫星代号集合
     * @param stationIdList   地面站代号集合
     * @param startTime       开始时间
     * @param endTime         结束时间
     */

    public void calcStation(List<String> satelliteIdList, List<String> stationIdList, String startTime, String endTime) {
        Date newstart = new Date(DateUtils.StringToDate(startTime).getTime() - 8 * 3600 * 1000);
        Date newend = new Date(DateUtils.StringToDate(endTime).getTime() - 8 * 3600 * 1000);
        startTime = DateUtils.DateToString(newstart);
        endTime = DateUtils.DateToString(newend);
        // 删除该时间内的资源信息
        trbutDataService.deleteList(satelliteIdList, stationIdList, 0, startTime, endTime);
        // 根据卫星代号集合查询卫星和轨道根数信息
        List<SatelliteAndInstanceRpcDTO> satelliteAndInstanceList = this.groupingData(satelliteIdList);
        // 根据地面站代号集合查询地面站信息
        List<QueryStationAddRpcDTO> stationListRpcDTO = infoBasisStationRpcService.getStationListByStationIdList(stationIdList);
        List<StationRpcDTO> stationList = new ArrayList<>();
        stationListRpcDTO.forEach(e -> {
            //增加中继星判断
            //todo 资源类型不等于1的均为地面站
            if (null == e.getResourceType() || Integer.parseInt(e.getResourceType()) == 0) {
                StationRpcDTO yxInfoBasisStationRpcDTO = new StationRpcDTO();
                BeanUtils.copyProperties(e, yxInfoBasisStationRpcDTO);
                stationList.add(yxInfoBasisStationRpcDTO);
            }
        });
        // 根据卫星代号集合和地面站代号集合查询站址信息
        List<SatelliteStationMatchRpcDTO> satelliteStationMatchList = satelliteStationMatchDTOService.getBySatelliteCodeAndStationCode(satelliteIdList, stationIdList);
        Objects.requireNonNull(satelliteStationMatchList, "根据卫星代号集合和地面站代号集合查询站址信息为空");
        // 查询指定的天文时间信息
        List<AstronomicalForecast> astronomicalForecastList = astronomicalForecastService.getAstronomicalForecastList(satelliteIdList, stationIdList, startTime, endTime, "sun_transit");
        Objects.requireNonNull(astronomicalForecastList, "查询指定的天文时间信息为空");
        // 获取可执行文件地址
        String filePath = Objects.requireNonNull(Objects.requireNonNull(ClassUtils.getDefaultClassLoader()).getResource("Orbit_EXE")).getPath().substring(1) + "/";
        // 遍历地面站信息
        for (StationRpcDTO station : stationList) {
            // 该地面站对应可用卫星的集合
            Set<String> satelliteCodeSet = satelliteStationMatchList.stream()
                    .filter(t -> t.getStationCode().equals(station.getStationCode()))
                    .map(SatelliteStationMatchRpcDTO::getSatelliteCode).collect(Collectors.toSet());
            if (satelliteCodeSet != null && satelliteCodeSet.size() > 0) {
                // 遍历卫星和轨道信息
                for (SatelliteAndInstanceRpcDTO satelliteAndInstance : satelliteAndInstanceList) {
                    // 卫星代号
                    String id = satelliteAndInstance.getYxInfoBasisSatelliteDTO().getSatelliteCode();
                    // 判断站址信息
                    if (satelliteCodeSet.contains(id)) {
                        // 获取该星该站的天文时间信息
                        List<AstronomicalForecast> astronomicalForecastListT = astronomicalForecastList.stream()
                                .filter(t -> t.getSatelliteId().equals(id) && t.getStationId().equals(station.getStationCode()))
                                .collect(Collectors.toList());
                        // 开启线程
                        /* trbutThread.run(filePath, station, satelliteAndInstance, startTime, endTime, astronomicalForecastListT);*/
                    }
                }
            }
        }
    }

    /**
     * 进出站计算
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     */
    @Countdlatch(TaskTypeEnum.ORBIT_NUM)
    public List<Task> calcTrbut(SubPointAop subPointAop) {
        List<String> satelliteCodes = subPointAop.getSatelliteCodes();
        List<String> stationIds = subPointAop.getStationIds();

        List<QueryStationAddRpcDTO> stations;
        if (CollectionUtils.isEmpty(stationIds)) {
            stations = stationRpcService.getStationListByStationIdList(new ArrayList<>());
        } else {
            stations = stationRpcService.getStationListByStationIdList(stationIds);
        }
        List<StationRpcDTO> stationList = new ArrayList<>();
        stations.forEach(e -> {
            //增加中继星判断
            //todo 资源类型不等于1的均为地面站
            if (null == e.getResourceType() || Integer.parseInt(e.getResourceType()) == 0) {
                StationRpcDTO yxInfoBasisStationRpcDTO = new StationRpcDTO();
                BeanUtils.copyProperties(e, yxInfoBasisStationRpcDTO);
                stationList.add(yxInfoBasisStationRpcDTO);
            }
        });

        List<SatelliteRpcDTO> satelliteRpcDTOList = satelliteService.listByIds(satelliteCodes);
        SatelliteRpcDTO satelliteRpcDTO = satelliteRpcDTOList.get(0);
        StationRpcDTO station = stationList.get(0);
        //轨道信息
        List<InstanceRpcDTO> listBySatelliteCode = instanceService.getListBySatelliteCode(satelliteCodes);

        List<Task> tasks = subPointAop.getTasks();
        for (Task task : tasks) {
            String startTime = task.getStartTime();
            String endTime = task.getEndTime();
            Date newstart = new Date(DateUtils.StringToDate(startTime).getTime() - 8 * 3600 * 1000);
            Date newend = new Date(DateUtils.StringToDate(endTime).getTime() - 8 * 3600 * 1000);
            startTime = DateUtils.DateToString(newstart);
            endTime = DateUtils.DateToString(newend);

            List<InstanceRpcDTO> collect = listBySatelliteCode.stream().filter(t -> t.getSatelliteCode().equals(satelliteRpcDTO.getSatelliteCode())).collect(Collectors.toList());
            List<InstanceRpcDTO> collect1 = collect.stream().sorted((o1, o2) -> o1.getEpochTime().compareTo(o2.getEpochTime())).collect(Collectors.toList());

            StationArcInput stationArcInput = new StationArcInput();

            BeanUtils.copyProperties(satelliteRpcDTO, stationArcInput);
            stationArcInput.setEarthGravityFieldModeOrde1(satelliteRpcDTO.getEarthGravityFieldModeOrde1() != null ? satelliteRpcDTO.getEarthGravityFieldModeOrde1() : "32.0");
            stationArcInput.setEarthGravityFieldModeOrde2(satelliteRpcDTO.getEarthGravityFieldModeOrde2() != null ? satelliteRpcDTO.getEarthGravityFieldModeOrde2() : "32.0");
            //最小跟踪仰角，默认3度
            stationArcInput.setAntMinTrackAngle(String.valueOf(station.getMinTraceElevation() == null ? 3 : station.getMinTraceElevation()));
            // 最小接收仰角，默认5度
            stationArcInput.setAntMinRecvElevation(String.valueOf(station.getMinWorkElevation() == null ? 5 : station.getMinWorkElevation()));
            // 日凌角，没有获取到数据的时候默认为 1 度
            stationArcInput.setSundialCorner(String.valueOf(station.getSundialCorner() == null ? 1 : station.getSundialCorner()));
            stationArcInput.setValue6(TimeUtil.format(new Date(collect1.get(0).getEpochTime().getTime() - 8 * 3600 * 1000)));
            stationArcInput.setValue7(TimeUtil.format(new Date(collect1.get(0).getEpochTime().getTime() - 8 * 3600 * 1000)));
            BeanUtils.copyProperties(collect1.get(0), stationArcInput);
            stationArcInput.setStartTime(startTime);
            stationArcInput.setStartTime1(startTime);
            stationArcInput.setEndTime(endTime);
            stationArcInput.setEndTime1(endTime);
            BeanUtils.copyProperties(station, stationArcInput);

            List<String> stringList = new ArrayList<>();
            stringList.add(satelliteRpcDTO.getSatelliteCode());
            task.setSatelliteCodes(stringList);
            task.setInput(stationArcInput);
            task.setStationCode(station.getStationCode());
            task.setStationName(station.getStationName());
            task.setSatelliteCode(satelliteRpcDTO.getSatelliteCode());
            task.setSatelliteName(satelliteRpcDTO.getSatelliteName());
            StationBaseBizInfo stationBaseBizInfo = new StationBaseBizInfo();
            stationBaseBizInfo.setStationId(station.getId());
            stationBaseBizInfo.setSatelliteId(satelliteRpcDTO.getId());
            task.setBaseBizInfo(stationBaseBizInfo);
        }
        return tasks;

    }

    /**
     * 轨道圈号计算
     *
     * @param satelliteIds
     * @param startTime
     * @param endTime
     */

    public void calcOrbitNum(List<String> satelliteIds, String startTime, String endTime) {
        // 清理库中的信息
        orbitNumService.deleteOrbitNumList(satelliteIds, startTime, endTime);
        // 获取卫星和轨道根数信息
        List<SatelliteAndInstanceRpcDTO> satelliteAndInstances = groupingData(satelliteIds);
        //获取可执行文件地址
        String filePath = Objects.requireNonNull(Objects.requireNonNull(ClassUtils.getDefaultClassLoader()).getResource("Orbit_EXE")).getPath().substring(1) + "/";
        //开启多线程计算
        for (SatelliteAndInstanceRpcDTO satelliteAndInstance : satelliteAndInstances) {
            orbitNumThread.run(filePath, satelliteAndInstance, startTime, endTime);
        }
    }

    /**
     * 天文事件计算
     *
     * @param satelliteIds
     * @param stationIds
     * @param startTime
     * @param endTime
     */

    public void calcAstronomy(List<String> satelliteIds, List<String> stationIds, String startTime, String endTime) {
        Date newstart = new Date(DateUtils.StringToDate(startTime).getTime() - 8 * 3600 * 1000);
        Date newend = new Date(DateUtils.StringToDate(endTime).getTime() - 8 * 3600 * 1000);
        startTime = DateUtils.DateToString(newstart);
        endTime = DateUtils.DateToString(newend);
        // 删除库中该星、该站和该时间范围内的信息
        astronomicalForecastService.deleteAstronomicalForecastList(satelliteIds, stationIds, startTime, endTime);
        // 获取卫星和轨道根数信息
        List<SatelliteAndInstanceRpcDTO> satelliteAndInstances = groupingData(satelliteIds);
        // 根据地面站代号集合查询地面站信息
        List<QueryStationAddRpcDTO> stationListRpcDTO = infoBasisStationRpcService.getStationListByStationIdList(stationIds);
        List<YxInfoBasisStationDTO> stationList = new ArrayList<>();
        stationListRpcDTO.forEach(e -> {
            YxInfoBasisStationDTO yxInfoBasisInstance = new YxInfoBasisStationDTO();
            BeanUtils.copyProperties(e, yxInfoBasisInstance);
            stationList.add(yxInfoBasisInstance);
        });
        // 根据卫星代号集合和地面站代号集合查询站址信息
        List<SatelliteStationMatchRpcDTO> satelliteStationMatchList = satelliteStationMatchDTOService.getBySatelliteCodeAndStationCode(satelliteIds, stationIds);
        //获取可执行文件地址
        String filePath = Objects.requireNonNull(Objects.requireNonNull(ClassUtils.getDefaultClassLoader()).getResource("Orbit_EXE")).getPath().substring(1) + "/";
        //开启多线程计算
        for (YxInfoBasisStationDTO station : stationList) {
            // 该地面站对应可用卫星的集合
            Set<String> satelliteCodeSet = satelliteStationMatchList.stream()
                    .filter(t -> t.getStationCode().equals(station.getStationCode()))
                    .map(SatelliteStationMatchRpcDTO::getSatelliteCode).collect(Collectors.toSet());
            for (SatelliteAndInstanceRpcDTO satelliteAndInstance : satelliteAndInstances) {
                if (satelliteCodeSet.contains(satelliteAndInstance.getYxInfoBasisSatelliteDTO().getSatelliteCode())) {
                    astronomyThread.run(filePath, station, satelliteAndInstance, startTime, endTime);
                }
            }
        }
    }

    /**
     * 根据卫星代号查询卫星和轨道根数信息
     * 1.验证卫星代号是否为空，若为空则查询所有卫星信息，不为空则查询卫星代号对应的卫星信息
     * 2.查询所有轨道根数信息，将轨道根数根据卫星代号分组
     * 3.将卫星信息和该卫星对应的历元时刻最晚的轨道根数信息放进同一个对象中，并将该对象添加进集合中
     *
     * @return
     */
    public List<SatelliteAndInstanceRpcDTO> groupingData(List<String> satelliteCodes) {
        // 查询卫星信息
        List<SatelliteRpcDTO> satelliteDOSRpcDTO;
        if (satelliteCodes.isEmpty()) {
            satelliteDOSRpcDTO = infoBasisSatelliteRpcService.list();
        } else {
            satelliteDOSRpcDTO = infoBasisSatelliteRpcService.listByIds(satelliteCodes);
        }
        if (satelliteDOSRpcDTO.size() == 0) {
            throw new AssertException("没有任何卫星信息");
        }
        List<YxInfoBasisSatelliteRpcDTO> satelliteDOS = new ArrayList<>();
        satelliteDOSRpcDTO.forEach(e -> {
            YxInfoBasisSatelliteRpcDTO yxInfoBasisSatelliteDTO = new YxInfoBasisSatelliteRpcDTO();
            BeanUtils.copyProperties(e, yxInfoBasisSatelliteDTO);
            satelliteDOS.add(yxInfoBasisSatelliteDTO);
        });
        // 查询瞬根信息
        List<InstanceRpcDTO> instanceDOSRpcDTO = infoBasisInstanceRpcService.queryNewestInstance();
        if (instanceDOSRpcDTO.size() == 0) {
            throw new AssertException("没有该时间范围内的瞬根信息");
        }

        List<YxInfoBasisInstanceRpcDTO> instanceDOS = new ArrayList<>();
        instanceDOSRpcDTO.forEach(e -> {
            YxInfoBasisInstanceRpcDTO yxInfoBasisInstanceDTO = new YxInfoBasisInstanceRpcDTO();
            BeanUtils.copyProperties(e, yxInfoBasisInstanceDTO);
            instanceDOS.add(yxInfoBasisInstanceDTO);
        });

        List<SatelliteAndInstanceRpcDTO> satelliteAndInstances = new ArrayList<>();
        // 按卫星分组，找到每个卫星历元时刻最新的瞬根,并将卫星实体作为key，方便计算
        Map<String, List<YxInfoBasisInstanceRpcDTO>> instanceGroupBySatelliteId = instanceDOS.stream().collect(Collectors.groupingBy(YxInfoBasisInstanceRpcDTO::getSatelliteCode));
        satelliteDOS.forEach(satelliteDO -> {
            List<YxInfoBasisInstanceRpcDTO> yxInfoBasisInstanceDOS = instanceGroupBySatelliteId.get(satelliteDO.getSatelliteCode());
            if (yxInfoBasisInstanceDOS != null && !yxInfoBasisInstanceDOS.isEmpty()) {
                satelliteAndInstances.add(new SatelliteAndInstanceRpcDTO(satelliteDO, yxInfoBasisInstanceDOS.stream().max(Comparator.comparing(YxInfoBasisInstanceRpcDTO::getEpochTime)).get()));
            }
        });
        return satelliteAndInstances;
    }

    public void fileroute(){
        try {
            Process exec = Runtime.getRuntime().exec(fileroute+"script.sh", null, new File(fileroute));
            exec.destroy();
        } catch (IOException e) {
            log.info("脚本文件执行失败: " + e);
            e.printStackTrace();
        }
    }

}

