package com.base.plan.trans;

import com.base.api.client.AntennaRpcService;
import com.base.api.client.PayloadRpcService;
import com.base.api.model.AntennaRpcDTO;
import com.base.api.model.PayloadRpcDTO;
import com.base.api.model.TrbutDataRpcDTO;
import com.base.orbit.utils.IdGenerator;
import com.base.plan.model.dto.StripDTO;
import com.base.plan.model.entity.WindowResource;
import com.base.plan.service.WindowResourceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 自定义数传策略
 */
@Service
@Slf4j
@DataTransCore(dataTransTypeEnums = DataTransTypeEnums.CUSTOM_DATA_TRANS)
public class CustomDataTransMissHandler implements DataTransmissHandler {

    @Resource
    PayloadRpcService payloadRpcService;
    @Resource
    WindowResourceService windowResourceService;
    @Resource
    AntennaRpcService antennaRpcService;

    /**
     * 根据选择一个或多个条带，一个或多个数传站进行数传规划
     *
     * @param stripDTOList
     * @param resourceList
     */
    @Override
    public Boolean trbutMake(List<StripDTO> stripDTOList, List<TrbutDataRpcDTO> resourceList) {
        if (stripDTOList.size() > 0 && resourceList.size() > 0) {
            //  todo 通过条带获取卫星载荷数传速率*时长得到内存占用 / 不同的站不同的天线口径不同的接收速率 = 时长
            //  todo 判断时长是否大于任务时长和地面站接收的时长
            stripDTOList.stream().forEach(stripDTO -> {
                stripDTO.setDuration(stripDTO.getObservationEndTime().getTime() - stripDTO.getObservationStartTime().getTime());
            });
            List<PayloadRpcDTO> payloadList = payloadRpcService.getAllList();
            // 窗口与资源关联信息
            List<WindowResource> windowResourceList = new ArrayList<>();


            List<String> stripList = stripDTOList.stream().map(StripDTO::getId).collect(Collectors.toList());
            List<String> trbutDataList = resourceList.stream().map(TrbutDataRpcDTO::getId).collect(Collectors.toList());
            List<List<String>> listAll = Arrays.asList(stripList, trbutDataList);
            List<List<String>> finalList = new LinkedList<>();
            combinationSelect(0, listAll, finalList, new LinkedList<>());


            // 循环条带
            stripDTOList.stream().forEach(dto -> {
                String satelliteCode = dto.getSatelliteCode();
                // 该卫星对应的载荷信息
                Optional<PayloadRpcDTO> payloadRpc = payloadList.stream().filter(t -> satelliteCode.equals(t.getSatelliteCode())).findFirst();
                if (payloadRpc.isPresent()) {
                    PayloadRpcDTO payloadRpcDTO = payloadRpc.get();
                    Double dataPassSpeed = Double.valueOf(payloadRpcDTO.getDataPassSpeed());             //  载荷速率
                    Double memoryUsage = dto.getDuration() * dataPassSpeed;                              //  星上内存占用

                    //  判断可用数传站能否满足数传要求
                    resourceList.stream().forEach(resource -> {
                        Optional<AntennaRpcDTO> antennaRpcDTO = antennaRpcService.selAntenaInfoByIds(Arrays.asList(resource.getStationCode())).stream().findFirst();
                        if (antennaRpcDTO.isPresent()) {
                            AntennaRpcDTO antennaRpcDTO1 = antennaRpcDTO.get();
                            Double jssl = Double.valueOf(antennaRpcDTO1.getJssl());
                            Double time = memoryUsage / jssl;     //  数传时间
                            if (time <= resource.getDuration()) {
                                WindowResource windowResource = buildWindowResource(dto.getId(), resource.getId());
                                windowResourceList.add(windowResource);
                            }
                        }
                    });
                }
            });

            if (!CollectionUtils.isEmpty(windowResourceList)) {
                //  选取的条带数传时间大于选取数传站接收时间
                windowResourceService.saveWindowResource(windowResourceList);
                return Boolean.TRUE;
            }
        }
        return Boolean.FALSE;
    }


    private WindowResource buildWindowResource(String windowId, String resourceId) {
        WindowResource windowResource = new WindowResource();
        windowResource.setId(IdGenerator.getStrId());
        windowResource.setWindowId(windowId);
        windowResource.setResourceId(resourceId);
        windowResource.setCreateTime(new Date());
        windowResource.setUpdateTime(new Date());
        return windowResource;
    }

    //  排列组合
    private static void combinationSelect(int index, List<List<String>> listAll, List<List<String>> finalList, List<String> currList) {
        if (index == listAll.size()) {
            finalList.add(currList);
            return;
        }
        for (String s : listAll.get(index)) {
            List<String> cList = new LinkedList<>(currList);
            cList.add(s);
            combinationSelect(index + 1, listAll, finalList, cList);
        }
    }


    public static void main(String[] args) {
        List<String> list1 = Arrays.asList("A", "B", "C", "D", "E");
        List<String> list2 = Arrays.asList("1", "2", "3", "4", "5");
        List<List<String>> listAll = Arrays.asList(list1, list2);


        List<List<String>> finalList = new LinkedList<>();
        combinationSelect(0, listAll, finalList, new LinkedList<>());
        finalList.forEach(System.out::println);

    }
}
