package com.css.simulation.resource.server.infra.runnable;

import api.common.pojo.constants.DictConstants;
import api.common.pojo.param.MinioParameter;
import api.common.pojo.param.scene.SceneEvaluationComputeParam;
import api.common.pojo.param.scene.SceneImportParam;
import api.common.pojo.po.scene.SceneComplexityPO;
import api.common.pojo.po.scene.SceneEvaluationRulePO;
import api.common.util.CollectionUtil;
import api.common.util.FileUtil;
import api.common.util.StringUtil;
import api.common.util.TimeUtil;
import com.alibaba.druid.util.StringUtils;
import com.css.simulation.resource.server.infra.db.mysql.mapper.SceneComplexityMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.SceneEvaluationRuleMapper;
import com.css.simulation.resource.server.infra.feign.service.FileDownService;
import com.css.simulation.resource.server.app.impl.ApplicationContextAwareImpl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static api.common.pojo.enums.SceneEvaluationEnum.matchLevelEnumByLevel;

/**
 * @author 15765
 * @date 2024/4/10 22:22
 */
@Slf4j
public class SceneEvaluationComputeRunnable implements Runnable {

    private final String linuxTempPath;
    private final SceneImportParam param;
    private final List<SceneEvaluationComputeParam> sceneEvaluationComputeParams;

    public SceneEvaluationComputeRunnable(SceneImportParam param, List<SceneEvaluationComputeParam> sceneEvaluationComputeParams, String linuxTempPath) {
        this.param = param;
        this.sceneEvaluationComputeParams = sceneEvaluationComputeParams;
        this.linuxTempPath = linuxTempPath;
    }

    @Override
    public void run() {
//        String ruleId = param.getSceneEvaluationRuleId();
//        log.info("开始执行线程：" + ruleId);
//        SceneEvaluationRuleMapper sceneEvaluationRuleMapper = ApplicationContextAwareImpl.getApplicationContext().getBean(SceneEvaluationRuleMapper.class);
//        SceneComplexityMapper sceneComplexityMapper = ApplicationContextAwareImpl.getApplicationContext().getBean(SceneComplexityMapper.class);
//        // 获取场景评价规则
//        SceneEvaluationRulePO sceneEvaluationRulePO = sceneEvaluationRuleMapper.querySceneEvaluationPyById(ruleId);
//        if (sceneEvaluationRulePO == null) {
//            log.error(ruleId + " 的场景评价规则已删除");
//            return;
//        }
//        log.info("场景评价规则为：" + sceneEvaluationRulePO);
//        // 1 判断有没有用户目录，没有则复制
//        String evaluationDirectoryOfUser = linuxTempPath + "scene/evaluation/" + sceneEvaluationComputeParams.get(0).getTaskId() + "/";
//        String scriptsPath = evaluationDirectoryOfUser + "scripts";
//        if (!new File(evaluationDirectoryOfUser).exists()) {
//            // 1 将场景评价规则脚本保存到 script 目录
//            FileUtil.createDirectory(scriptsPath);
//        }
//
//        // 下载场景评价脚本到脚本目录
//        if (sceneEvaluationRulePO.getScriptPath() == null) {
//            return;
//        }
//        String pyMainPath = scriptsPath + "/" + sceneEvaluationRulePO.getRuleId();
//        if (!new File(pyMainPath).exists()) {
//            try {
//                downloadDependFile(sceneEvaluationRulePO.getScriptPath(), pyMainPath);
//                Path path = Paths.get(pyMainPath);
//                Set<PosixFilePermission> permissions = new HashSet<>();
//                permissions.add(PosixFilePermission.OWNER_READ);
//                permissions.add(PosixFilePermission.OWNER_WRITE);
//                permissions.add(PosixFilePermission.OWNER_EXECUTE);
//                permissions.add(PosixFilePermission.GROUP_READ);
//                permissions.add(PosixFilePermission.GROUP_WRITE);
//                permissions.add(PosixFilePermission.GROUP_EXECUTE);
//                permissions.add(PosixFilePermission.OTHERS_READ);
//                permissions.add(PosixFilePermission.OTHERS_WRITE);
//                permissions.add(PosixFilePermission.OTHERS_EXECUTE);
//                Files.setPosixFilePermissions(path, permissions);
//            } catch (IOException e) {
//                log.error("下载执行文件失败： " + sceneEvaluationRulePO.getScriptPath(), e);
//                return;
//            }
//        }
//        String scenePathFather = evaluationDirectoryOfUser + "scene/";
//        for (SceneEvaluationComputeParam sceneEvaluationComputeParam : sceneEvaluationComputeParams) {
//            // 创建场景路径
//            String scenePath = scenePathFather + sceneEvaluationComputeParam.getSceneId();
//            if (!new File(scenePath).exists()) {
//                FileUtil.createDirectory(scenePath);
//            } else {
//                // 一个场景只计算一次
//                return;
//            }
//            try {
//                if (StringUtils.equals(sceneEvaluationComputeParam.getComputeType(), DictConstants.COMPLEXITY)) {
//                    if (StringUtil.isEmpty(sceneEvaluationComputeParam.getSceneXODRPath())
//                            || StringUtil.isEmpty(sceneEvaluationComputeParam.getSceneXOSCPath())) {
//                        continue;
//                    }
//                    // 计算复杂度，根据场景 id 获取场景信息，下载 osc odr
//                    String scenarioOsc = sceneEvaluationComputeParam.getSceneXOSCPath();
//                    String[] splitXosc = scenarioOsc.split("/");
//                    String xoscName = splitXosc[splitXosc.length - 1];
//                    downloadDependFile(sceneEvaluationComputeParam.getSceneXOSCPath(), scenePath + "/" + xoscName);
//
//                    String scenarioOdr = sceneEvaluationComputeParam.getSceneXODRPath();
//                    String[] splitXodr = scenarioOdr.split("/");
//                    String xodrName = splitXodr[splitXodr.length - 1];
//                    downloadDependFile(sceneEvaluationComputeParam.getSceneXODRPath(), scenePath + "/" + xodrName);
//                } else {
//                    return;
//                }
//            } catch (IOException e) {
//                log.error("文件下载失败", e);
//                FileUtil.deleteFolder(scenePath);   // 删除临时文件
//            }
//        }
//        String sceneEvaluationCommand;
//        if (StringUtils.equals(sceneEvaluationComputeParams.get(0).getComputeType(), DictConstants.COMPLEXITY)) {
//            sceneEvaluationCommand = pyMainPath + " " + scenePathFather + " complexity";
//        } else {
//            sceneEvaluationCommand = pyMainPath + " " + scenePathFather + " criticality";
//        }
//        String sceneEvaluationResult;
//        log.info("开始执行场景评价命令：" + sceneEvaluationCommand);
//        Runtime r = Runtime.getRuntime();
//        Process p;
//        try {
//            p = r.exec(sceneEvaluationCommand);
//        } catch (IOException e) {
//            log.error("执行场景评价脚本失败，脚本命令为： " + sceneEvaluationCommand, e);
//            return;
//        }
//
//        StringBuilder sb = new StringBuilder();
//        try {
//            BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
//            String inline;
//            while ((inline = br.readLine()) != null) {
//                sb.append(inline).append("\n");
//            }
//            br.close();
//        } catch (IOException e) {
//            log.error("获取场景评价脚本返回内容失败", e);
//            return;
//        }
//        sceneEvaluationResult = sb.toString();
//        log.info("场景评价结束，结果为：" + sceneEvaluationResult);
//        for (SceneEvaluationComputeParam sceneEvaluationComputeParam : sceneEvaluationComputeParams) {
//            // 读文件
//            StringBuilder result = new StringBuilder();
//            try {
//                FileInputStream fileInputStream = new FileInputStream(scenePathFather + sceneEvaluationComputeParam.getSceneId() + "/scenario_evaluation.json");
//                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
//
//                String line;
//                while ((line = bufferedReader.readLine()) != null) {
//                    result.append(line).append("\n");
//                }
//                bufferedReader.close();
//            } catch (IOException e) {
//                log.error("读取场景评价结果失败", e);
//                continue;
//            }
//            String resultStr = result.toString();
//            String replace = StringUtil.replace(resultStr, "'", "\"");
//            JsonNode rootNode;
//            try {
//                ObjectMapper mapper = new ObjectMapper();
//                //JSON ----> JsonNode
//                rootNode = mapper.readTree(replace);
//
//                if (StringUtils.equals(sceneEvaluationComputeParam.getComputeType(), DictConstants.COMPLEXITY)) {
//                    String complexity = rootNode.path("复杂度").asText();
//                    String complexityLevel = rootNode.path("复杂度等级").asText();
//                    SceneComplexityPO sceneComplexityPO = new SceneComplexityPO();
//                    sceneComplexityPO.setSceneId(sceneEvaluationComputeParam.getSceneId());
//                    sceneComplexityPO.setComplexityId(StringUtil.getRandomUUID());
//                    sceneComplexityPO.setSceneType(sceneEvaluationComputeParam.getSceneType());
//                    sceneComplexityPO.setRuleId(ruleId);
//                    sceneComplexityPO.setTaskId(sceneEvaluationComputeParam.getTaskId());
//                    sceneComplexityPO.setComplexity(complexity);
//                    sceneComplexityPO.setComplexityLevel(matchLevelEnumByLevel(complexityLevel));
//                    sceneComplexityPO.setIsDeleted(DictConstants.IS_NOT_DELETED);
//                    sceneComplexityPO.setCreateUserId(sceneEvaluationComputeParam.getCreateUserId());
//                    sceneComplexityPO.setCreateTime(TimeUtil.getNowForMysql());
//                    sceneComplexityMapper.saveSceneComplexity(sceneComplexityPO);
//                    if (CollectionUtil.isNotEmpty(sceneEvaluationComputeParam.getCopySceneId())) {
//                        copySceneComplexityResult(sceneEvaluationComputeParam.getTaskId(), sceneEvaluationComputeParam.getSceneId(), sceneEvaluationComputeParam.getCopySceneId());
//                    }
//                }
//            } catch (Exception e) {
//                log.error("场景" + sceneEvaluationComputeParam.getSceneId() + " 的场景评价失败：", e);
//            }
//        }
//        // 删除临时文件
//        FileUtil.deleteFolder(linuxTempPath + "scene/evaluation/" + sceneEvaluationComputeParams.get(0).getTaskId());   // 删除临时文件
//    }
//
//
//    private void downloadDependFile(String minioPath, String localPath) throws IOException {
//        FileDownService fileDownService = ApplicationContextAwareImpl.getApplicationContext().getBean(FileDownService.class);
//        Response download = fileDownService.download(MinioParameter.builder().objectName(minioPath).build());
//        Response.Body body = download.body();
//        InputStream inputStream;
//        inputStream = body.asInputStream();
//        File file = new File(localPath);
//        OutputStream outputStream = Files.newOutputStream(file.toPath());
//        byte[] buffer = new byte[1024];
//        int bytesRead;
//        while ((bytesRead = inputStream.read(buffer)) != -1) {
//            outputStream.write(buffer, 0, bytesRead);
//        }
//        inputStream.close();
//        outputStream.close();
//        download.close();
    }

    public void copySceneComplexityResult(String taskId, String tempSceneId, List<String> copySceneIds) {
        SceneComplexityMapper sceneComplexityMapper = ApplicationContextAwareImpl.getApplicationContext().getBean(SceneComplexityMapper.class);
        List<SceneComplexityPO> sceneComplexityPOS = sceneComplexityMapper.selectSceneComplexityEvaluation(taskId, tempSceneId);
        List<SceneComplexityPO> saveList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(sceneComplexityPOS)) {
            for (SceneComplexityPO sceneComplexityPO : sceneComplexityPOS) {
                for (String copySceneId : copySceneIds) {
                    SceneComplexityPO tempComplexityPO = new SceneComplexityPO();
                    BeanUtils.copyProperties(sceneComplexityPO, tempComplexityPO);
                    tempComplexityPO.setSceneId(copySceneId);
                    tempComplexityPO.setComplexityId(StringUtil.getRandomUUID());
                    saveList.add(tempComplexityPO);
                }
            }
            if (CollectionUtil.isNotEmpty(saveList)) {
                sceneComplexityMapper.saveSceneComplexityS(saveList);
            }
        }
    }
}
