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

import api.common.pojo.constants.DictConstants;
import api.common.pojo.param.project.SimulationManualProjectParam;
import api.common.pojo.po.project.SimulationManualProjectPO;
import api.common.pojo.po.scheduler.SchedulerProjectPO;
import api.common.util.StringUtil;
import com.css.simulation.resource.server.infra.db.mysql.mapper.AlgorithmMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.ModelConfigMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.ModelVehicleMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.AutoSubProjectMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.ManualProjectMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.SimulationManualProjectMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.ScenePackageMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.ScenePackageSublistMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
@Slf4j
public class ProjectUtil {

    @Resource
    private ManualProjectMapper manualProjectMapper;
    @Resource
    private AutoSubProjectMapper autoSubProjectMapper;
    @Resource
    private SimulationManualProjectMapper simulationManualProjectMapper;
    @Resource
    private ScenePackageMapper scenePackageMapper;
    @Resource
    private AlgorithmMapper algorithmMapper;
    @Resource
    private ModelConfigMapper modelConfigMapper;
    @Resource
    private ModelVehicleMapper modelVehicleMapper;
    @Resource
    private ScenePackageSublistMapper scenePackageSublistMapper;
    @Resource
    private SceneUtil sceneUtil;


    public String getProjectTypeByProjectId(String projectId) {
        String projectType = null;
        SchedulerProjectPO manualProjectPO = manualProjectMapper.selectById(projectId);
        SchedulerProjectPO autoSubProjectPO = autoSubProjectMapper.selectById(projectId);
        if (manualProjectPO != null) {
            projectType = DictConstants.PROJECT_TYPE_MANUAL;
        } else if (autoSubProjectPO != null) {
            projectType = DictConstants.PROJECT_TYPE_AUTO_SUB;
        }
        return projectType;
    }

    public static String getEvaluationLevelReport(double algorithmScore) {
        if (algorithmScore >= 90) {
            return DictConstants.REPORT_LEVEL_G;
        } else if (algorithmScore >= 80) {
            return DictConstants.REPORT_LEVEL_A;
        } else if (algorithmScore >= 70) {
            return DictConstants.REPORT_LEVEL_M;
        } else {
            return DictConstants.REPORT_LEVEL_P;
        }
    }


    public SimulationManualProjectPO getProjectInfo(SimulationManualProjectParam param) {
        if (StringUtil.isEmpty(param.getId()) || StringUtil.isEmpty(param.getNowRunState())) {
            throw new RuntimeException("参数为空。");
        } else {
            SimulationManualProjectPO po = simulationManualProjectMapper.selectProjectById(param);
            if (po == null) {
                throw new RuntimeException("手动项目" + param.getId() + "不存在。");
            }
            return po;
        }
    }

    public void checkProject(String algorithmId, String vehicleConfigId, String scenePackageId, int parallelism) {
        //* -------------------------------- Comment --------------------------------
        log.info("1 检查算法是否被删除：" + algorithmId);
        if (DictConstants.IS_DELETED.equals(algorithmMapper.selectIsDeletedById(algorithmId))) {
            throw new RuntimeException("项目所使用算法已被删除。");
        }
        //* -------------------------------- Comment --------------------------------
        log.info("1 查询车辆配置是否被删除：" + vehicleConfigId);
        if (DictConstants.IS_DELETED.equals(modelConfigMapper.selectIsDeletedByConfigId(vehicleConfigId))) {
            throw new RuntimeException("项目所使用的车辆配置已被删除。");
        }
        log.info("2 查询车辆配置是否被禁用：" + vehicleConfigId);
        final String isUnavailable1 = modelConfigMapper.selectIsUnavailableByModelConfigId(vehicleConfigId);
        if (DictConstants.IS_UNAVAILABLE.equals(isUnavailable1)) {
            throw new RuntimeException("车辆配置已被禁用。");
        }
        log.info("3 查询车辆配置中是否存在车辆模型：" + vehicleConfigId);
        final String vehicleIsDeleted = modelVehicleMapper.selectIsDeletedByConfigId(vehicleConfigId);
        if (DictConstants.IS_DELETED.equals(vehicleIsDeleted)) {
            throw new RuntimeException("车辆配置绑定的动力学配置已被删除。");
        }
        //* -------------------------------- Comment --------------------------------
        log.info("1 查询场景测试包是否被删除：" + scenePackageId);
        String packageIsDeleted = scenePackageMapper.selectIsDeletedByPackageId(scenePackageId);
        if (DictConstants.IS_DELETED.equals(packageIsDeleted)) {
            throw new RuntimeException("场景测试包已被删除。");
        }
        log.info("2 查询场景测试包是否被禁用：" + scenePackageId);
        String isUnavailable2 = scenePackageMapper.selectIsUnavailableByPackageId(scenePackageId);
        if (DictConstants.IS_UNAVAILABLE.equals(isUnavailable2)) {
            throw new RuntimeException("场景测试包已被禁用，编辑场景测试包后可重新运行。");
        }
        log.info("3 查询评分规则是否被删除。");
        sceneUtil.checkRules(scenePackageId);
        log.info("4 查询场景测试包是否有场景。");
        final int sceneNum = scenePackageSublistMapper.selectSceneNumByPackageId(scenePackageId);
        if (sceneNum == 0) {
            throw new RuntimeException("场景测试包内的场景已被全部删除，请添加场景。");
        }
        log.info("5 判断并行度 " + parallelism + "是否大于场景测试包内场景数量：" + sceneNum);
        if (sceneNum < parallelism) {
            throw new RuntimeException("并行度 " + parallelism + " 大于场景测试包内场景数量 " + sceneNum + " ，请修改并行度。");
        }

    }
}
