package com.css.simulation.resource.scheduler;


import api.common.util.CollectionUtil;
import api.common.util.StringUtil;
import api.common.util.TimeUtil;
import com.css.simulation.resource.scheduler.mapper.IndexTemplateMapper;
import com.css.simulation.resource.scheduler.mapper.TaskIndexMapper;
import com.css.simulation.resource.scheduler.mapper.TaskMapper;
import com.css.simulation.resource.scheduler.pojo.po.IndexTemplatePO;
import com.css.simulation.resource.scheduler.pojo.po.TaskIndexPO;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class SchedulerTest {

    @Autowired
    TaskIndexMapper taskIndexMapper;
    @Autowired
    TaskMapper taskMapper;
    @Autowired
    IndexTemplateMapper indexTemplateMapper;
    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    ApiClient apiClient;

    private final String USER_ID = "simulation-resource-scheduler";


    @Test
    public void redisTemplate() throws ApiException {
        redisTemplate.opsForValue().set("a:b","test");
        redisTemplate.opsForValue().set("a:b:c","test");
    }

    @Test
    public void test() {


        List<TaskIndexPO> leafTaskIndexList = new ArrayList<>();
        TaskIndexPO taskIndexPO1 = TaskIndexPO.builder()
                .id("9e64a4aa3df7414097ffd1c82a8bdaa3")
                .pId("7586e4196699414d87f63ffbbf281122")
                .indexId("12db82c7acbf49a6a9274243e7eebc6a")
                .parentId("046155104e934910b19305a6ba27a784")
                .rootId("059c582c7cf3422b8d9bb8583f6b7c5a")
                .target("12db82c7acbf49a6a9274243e7eebc6a")
                .notStandardSceneNum(0)
                .score(100.0)
                .weight("50")
                .scoreExplain("1) 未发生碰撞,得分 100;2) 发生碰撞,得分 0。)")
                .build();
        leafTaskIndexList.add(taskIndexPO1);

        TaskIndexPO taskIndexPO2 = TaskIndexPO.builder()
                .id("fc16c0aa3292496fb37daa635dd2d506")
                .pId("7586e4196699414d87f63ffbbf281122")
                .indexId("393a4b959d684eec9b5b777c8fc38bcf")
                .parentId("046155104e934910b19305a6ba27a784")
                .rootId("059c582c7cf3422b8d9bb8583f6b7c5a")
                .target("393a4b959d684eec9b5b777c8fc38bcf")
                .notStandardSceneNum(0)
                .score(100.0)
                .weight("50")
                .scoreExplain("1) 未发生碰撞,得分 100;2) 发生碰撞,得分 0。)")
                .build();
        leafTaskIndexList.add(taskIndexPO2);

        TaskIndexPO taskIndexPO3 = TaskIndexPO.builder()
                .id("300fbafab2d3432aac2b7926bb89456a")
                .pId("7586e4196699414d87f63ffbbf281122")
                .indexId("5b95a89d5a764af0ad93164753ab8caa")
                .parentId("059c582c7cf3422b8d9bb8583f6b7c5a")
                .rootId("059c582c7cf3422b8d9bb8583f6b7c5a")
                .target("5b95a89d5a764af0ad93164753ab8caa")
                .notStandardSceneNum(0)
                .score(100.0)
                .weight("60")
                .scoreExplain("1) 未发生碰撞,得分 100;2) 发生碰撞,得分 0。)")
                .build();
        leafTaskIndexList.add(taskIndexPO3);

        computeFirst(leafTaskIndexList, "7586e4196699414d87f63ffbbf281122");
    }

    public void computeFirst(List<TaskIndexPO> leafTaskIndexList, String projectId) {

        log.info("------- /state computeFirst 计算父指标得分:" + leafTaskIndexList);
        Iterator<TaskIndexPO> leafTaskIndexIterator = leafTaskIndexList.iterator();
        while (leafTaskIndexIterator.hasNext()) {
            TaskIndexPO leafTaskIndex = leafTaskIndexIterator.next();
            String parentId = leafTaskIndex.getParentId();
            String rootId = leafTaskIndex.getRootId();
            if (parentId.equals(rootId)) {
                leafTaskIndex.setCreateUserId(USER_ID);
                leafTaskIndex.setCreateTime(TimeUtil.getNowForMysql());
                leafTaskIndex.setModifyUserId(USER_ID);
                leafTaskIndex.setModifyTime(TimeUtil.getNowForMysql());
                leafTaskIndex.setIsDeleted("0");
                taskIndexMapper.insertFirstIndex(leafTaskIndex);
                leafTaskIndexIterator.remove();
            }

        }
        if (leafTaskIndexList.size() > 0) {
            Map<String, List<TaskIndexPO>> sonTaskIndexMap = leafTaskIndexList.stream().collect(Collectors.groupingBy(TaskIndexPO::getParentId));
            Set<String> parentIdSet = sonTaskIndexMap.keySet();
            List<String> parentIdList = CollectionUtil.setToList(parentIdSet);
            List<IndexTemplatePO> parentIndexTemplateList = indexTemplateMapper.selectByIdList(parentIdList);
            // 计算父指标得分
            List<TaskIndexPO> parentIndexList = new ArrayList<>();
            parentIndexTemplateList.forEach(indexTemplate -> {
                String weight = indexTemplate.getWeight();

                List<TaskIndexPO> sonTaskIndexList = sonTaskIndexMap.get(indexTemplate.getIndexId());
                double parentScore = sonTaskIndexList.stream().mapToDouble(taskIndex -> taskIndex.getScore() * Double.parseDouble(taskIndex.getWeight()) / 100).sum();
                TaskIndexPO parentTaskIndex = TaskIndexPO.builder()
                        .id(StringUtil.getRandomUUID())
                        .pId(projectId)
                        .target(indexTemplate.getIndexId())
                        .score(parentScore)
                        .indexId(indexTemplate.getIndexId())
                        .parentId(indexTemplate.getParentId())
                        .rootId(indexTemplate.getRootId())
                        .weight(weight)
                        .build();
                parentIndexList.add(parentTaskIndex);
            });
            // 将父指标作为叶子指标递归
            computeFirst(parentIndexList, projectId);
        }
    }

}