package com.css.simulation.resource.scene.controller;

import api.common.pojo.common.ResponseBodyVO;
import api.common.pojo.constants.DictConstants;
import api.common.pojo.param.scene.SceneImportParam;
import api.common.pojo.po.scene.SceneEvaluationRulePO;
import api.common.pojo.po.system.SceneEvaluationRuleScriptPO;
import api.common.pojo.po.system.SceneImportPO;
import api.common.util.StringUtil;
import api.common.util.TimeUtil;
import com.css.simulation.resource.scene.common.oauth.AuthorizationHolder;
import com.css.simulation.resource.scene.common.feign.SceneService;
import com.css.simulation.resource.scene.common.utils.AuthUtil;
import com.css.simulation.resource.scene.service.SceneImportService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.Date;

@Controller
@Slf4j
@RequestMapping("/sceneImport")
public class SceneImportController {

    @Resource
    SceneImportService sceneImportService;

    @Resource
    SceneService sceneService;

    /**
     * 先上传到 minio 然后解析
     */
    @RequestMapping("/startImport")
    @ResponseBody
    public ResponseBodyVO<String> startImport(@RequestBody SceneImportPO po, HttpServletRequest request) {
        try {
            //* -------------------------------- 路径校验 --------------------------------
            Boolean directory = sceneImportService.checkDirectory(po);
            if (!directory) {
                po.setErrorMessage("路径错误: " + po.getDataDirectory());
                po.setStatus(DictConstants.SCENE_IMPORT_STATUS_0);
                sceneImportService.updateStatus(po);
                return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE);
            }
            //* -------------------------------- 上传到 minio --------------------------------
            po.setStatus(DictConstants.SCENE_IMPORT_STATUS_1);
            sceneImportService.updateStatus(po);
            log.info("上传到minio " + po);
            Boolean sceneType = sceneImportService.startImport(po); // 上传
            if (!sceneType) {
                po.setErrorMessage("场景类型错误！");
                po.setStatus(DictConstants.SCENE_IMPORT_STATUS_0);
                sceneImportService.updateStatus(po);
                return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE);
            }
            po.setStatus(DictConstants.SCENE_IMPORT_STATUS_2);
            sceneImportService.updateStatus(po);
        } catch (Exception e) {
            e.printStackTrace();
            po.setStatus(DictConstants.SCENE_IMPORT_STATUS_0);
            po.setErrorMessage("上传失败");
            sceneImportService.updateStatus(po);
            return new ResponseBodyVO<>(ResponseBodyVO.Response.SERVER_FAILURE);
        }
        //* -------------------------------- 解析 --------------------------------
        SceneImportParam param = new SceneImportParam();
        param.setId(po.getId());
        param.setMinioDirectory(po.getDataDirectory());
        param.setSceneEvaluationRuleId(po.getSceneEvaluationRuleId());
        String authorization = request.getHeader("Authorization");
        AuthorizationHolder.setAuthorization(authorization);
        switch (po.getSceneType()) {
            case DictConstants.SCENE_NATURAL:
                sceneService.saveSceneNaturalBatch(param);  //自然驾驶
                break;
            case DictConstants.SCENE_STANDARD:  // 标准法规
                sceneService.saveStandardsRegulationsBatch(param);
                break;
            case DictConstants.SCENE_ACCIDENT:  // 交通事故
                sceneService.saveSceneAccidentBatch(param);
                break;
            case DictConstants.SCENE_REFERENCE_LIB:  // 基准场景库
                sceneService.saveSceneReferenceLibBatch(param);
                break;
        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
    }

    @RequestMapping("/startImportEvaluationScript")
    @ResponseBody
    public ResponseBodyVO<String> startImportEvaluationScript(@RequestBody SceneEvaluationRuleScriptPO po) {
        File file = new File(po.getLocalPath());
        SceneEvaluationRulePO sceneEvaluationRulePO = new SceneEvaluationRulePO();
        sceneEvaluationRulePO.setRuleId(po.getRuleId());
        if (!file.exists()) {
            sceneEvaluationRulePO.setStatus(DictConstants.SCENE_IMPORT_STATUS_0);
            sceneEvaluationRulePO.setErrorMsg("路径错误，文件不存在");
            sceneImportService.updateSceneEvaluationRule(sceneEvaluationRulePO);
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE);
        }
        Integer nowTime = TimeUtil.getRq(new Date(), 0);
        String randomCode = StringUtil.getRandomCode();
        String objectPath = "场景评价可执行文件/" + nowTime + "/" + randomCode + "/";
        try {
            //* -------------------------------- 上传到 minio --------------------------------
            log.info("上传到minio " + objectPath);
            String fileName = file.getName();
            boolean uploadSuccess = sceneImportService.startUploadEvaluationScript(objectPath, fileName, po.getLocalPath());
            if (!uploadSuccess) {
                sceneEvaluationRulePO.setStatus(DictConstants.SCENE_IMPORT_STATUS_0);
                sceneEvaluationRulePO.setErrorMsg("文件上传失败");
                sceneImportService.updateSceneEvaluationRule(sceneEvaluationRulePO);
                return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE);
            }
            // 删除历史可执行文件
            SceneEvaluationRulePO oldSceneEvaluationRule = sceneImportService.querySceneEvaluationRuleById(po.getRuleId());
            if (oldSceneEvaluationRule != null && StringUtil.isNotEmpty(oldSceneEvaluationRule.getScriptPath())) {
                try {
                    sceneImportService.deleteOldSceneEvaluationRuleFile(oldSceneEvaluationRule.getScriptPath());
                } catch (Exception e) {
                    sceneEvaluationRulePO.setErrorMsg("删除历史场景评价文件失败");
                }
            }
            sceneEvaluationRulePO.setScriptName(fileName);
            sceneEvaluationRulePO.setScriptPath(objectPath + fileName);
            sceneEvaluationRulePO.setStatus(DictConstants.SCENE_IMPORT_STATUS_2);
            sceneEvaluationRulePO.setErrorMsg("");
            sceneImportService.updateSceneEvaluationRule(sceneEvaluationRulePO);
        } catch (Exception e) {
            log.error("上传可执行文件失败：" + po.getRuleId(), e);
            sceneImportService.deleteOldSceneEvaluationRuleFile(objectPath);
            sceneEvaluationRulePO.setStatus(DictConstants.SCENE_IMPORT_STATUS_0);
            sceneEvaluationRulePO.setErrorMsg("上传失败");
            sceneEvaluationRulePO.setModifyTime(TimeUtil.getNowForMysql());
            sceneEvaluationRulePO.setModifyUserId(AuthUtil.getCurrentUserId());
            sceneImportService.updateSceneEvaluationRule(sceneEvaluationRulePO);
            return new ResponseBodyVO<>(ResponseBodyVO.Response.SERVER_FAILURE);
        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
    }
}
