package com.css.simulation.resource.server.app.service;

import api.common.pojo.constants.DictConstants;
import api.common.pojo.param.model.VehicleParam;
import api.common.pojo.po.model.ConfigPO;
import api.common.pojo.po.model.VehiclePO;
import api.common.pojo.vo.model.VehicleGSVO;
import api.common.pojo.vo.model.VehicleVO;
import api.common.util.*;
import com.css.simulation.resource.server.infra.util.AuthUtil;
import com.css.simulation.resource.server.infra.feign.service.FileDownService;
import com.css.simulation.resource.server.infra.db.mysql.mapper.ModelConfigMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.VehicleMapper;
import com.css.simulation.resource.server.infra.util.VehicleUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.buf.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;

@Slf4j
@Service
public class VehicleService {
    @Value("${par.template}")
    private String parTemplate;
    @Value("${par.temp}")
    private String parTemp;
    @Resource
    private VehicleMapper vehicleMapper;
    @Resource
    private FileDownService fileDownService;
    @Resource
    private ModelConfigMapper modelConfigMapper;

    //* -------------------------------- Comment --------------------------------
    public void delVehicleById(VehiclePO vehiclePO) {
        //1 将车辆相关的车辆配置修改为已禁用
        ConfigPO configPO = new ConfigPO();
        configPO.setIsUnavailable(DictConstants.IS_UNAVAILABLE);
        configPO.setVehicleId(vehiclePO.getId());
        configPO.setModifyUserId(AuthUtil.getCurrentUserId());
        configPO.setModifyTime(TimeUtil.getNowForMysql());
        modelConfigMapper.updateIsUnavailableByVehicleId(configPO);
        //2 删除车辆
        String currentUserId = AuthUtil.getCurrentUserId();
        Timestamp currentTime = TimeUtil.getNowForMysql();
        vehiclePO.setModifyUserId(currentUserId);
        vehiclePO.setModifyTime(currentTime);
        vehiclePO.setIsDeleted(DictConstants.YES);
        LogUtil.delete();
        vehicleMapper.delVehicleById(vehiclePO);
    }
    //* -------------------------------- Comment --------------------------------

    public List<VehicleVO> getVehicleList(VehicleParam vehicleParam) {
        vehicleParam.setCreateUserId(AuthUtil.getCurrentUserId());
        vehicleParam.setShare(null);
        return vehicleMapper.getVehicleList(vehicleParam);
    }

    public List<VehicleVO> getMyVehicleList() {
        return vehicleMapper.selectPrivateAndPublicByCreateUserId(AuthUtil.getCurrentUserId());
    }

    public VehicleVO getVehicleInfo(VehicleParam vehicleParam) {
        VehicleVO vehicleInfo = vehicleMapper.getVehicleInfo(vehicleParam);
        String parameterType = vehicleInfo.getParameterType();
        if ("2".equals(parameterType)) {
            VehicleUtil.jsonToList(vehicleInfo);
        }
        //车辆模型字段解析
        String vehicleType = vehicleInfo.getVehicleTypeStr();
        vehicleInfo.setVehicleType(vehicleType.split(","));
        return vehicleInfo;
    }

    @SneakyThrows
    public VehiclePO saveVehicle(VehicleVO vehicleVO) {
        log.info("车辆 vo 为：" + vehicleVO);
        VehiclePO vehiclePO = ObjectUtil.vehicleVoToVehiclePo(vehicleVO);
        //车辆模型字段解析
        if (ObjectUtil.isNotNull(vehicleVO.getVehicleType())) {
            vehiclePO.setVehicleType(StringUtils.join(Arrays.asList(vehicleVO.getVehicleType()), ','));
        }
        //常规字段赋值
        String currentUserId = AuthUtil.getCurrentUserId();
        Timestamp currentTime = TimeUtil.getNowForMysql();
        vehiclePO.setCreateUserId(currentUserId);
        vehiclePO.setCreateTime(currentTime);
        vehiclePO.setModifyUserId(currentUserId);
        vehiclePO.setModifyTime(currentTime);
        vehiclePO.setIsDeleted(DictConstants.NO);
        vehiclePO.setShare(DictConstants.NO);//私有
        //名称校验
        List<VehicleVO> list = vehicleMapper.checkVehicleName(vehiclePO);
        if (ObjectUtil.isNotNull(list)) {
            vehiclePO.setId(null);
            return vehiclePO;
        }
        log.info("车辆名称校验通过。");
        String id = vehiclePO.getId();

        String parameterType = vehicleVO.getParameterType();    //1 判断参数是 1 vtd 还是 2 carsim
        if ("2".equals(parameterType)) {
            if ("0".equals(vehicleVO.getSaveOrShare())) {
                VehicleUtil.listToJson(vehiclePO);
            }
            if ("1".equals(vehicleVO.getSaveOrShare())) {
                VehicleUtil.jsonToList(vehicleVO);
            }
            String par = FileUtil.read(parTemplate);
            log.info("车辆 po 为：" + vehiclePO);
            final String gearRatioJson = vehiclePO.getGearRatioJson();
            final List<String> gearRatio;
            if (CollectionUtil.isNotEmpty(vehiclePO.getGearRatio())) {
                gearRatio = vehiclePO.getGearRatio();
            } else {
                gearRatio = JsonUtil.jsonToList(gearRatioJson, String.class);
            }
            StringBuilder gearRatioString = new StringBuilder();
            for (int i = 0; i < gearRatio.size(); i++) {
                if (i == 0) {
                    gearRatioString.append("R_GEAR_TR_REVERSE ").append(gearRatio.get(0)).append(System.lineSeparator());
                    continue;
                }
                if (i == 1) {
                    continue;
                }
                gearRatioString.append("IGEAR ").append(i - 1).append(System.lineSeparator());
                gearRatioString.append("R_GEAR_TR ").append(gearRatio.get(i)).append(System.lineSeparator());
                gearRatioString.append("*R_GEAR_TR(").append(i - 1).append(") ").append(gearRatio.get(i)).append(System.lineSeparator());
            }

            final String inertiaJson = vehiclePO.getInertiaJson();
            final List<String> inertia;
            if (CollectionUtil.isNotEmpty(vehiclePO.getInertia())) {
                inertia = vehiclePO.getInertia();
            } else {
                inertia = JsonUtil.jsonToList(inertiaJson, String.class);
            }
            StringBuilder inertiaString = new StringBuilder();
            for (int i = 0; i < inertia.size(); i++) {
                if (i == 0) {
                    inertiaString.append("ITR_REVERSE ").append(inertia.get(0)).append(System.lineSeparator());
                    continue;
                }
                if (i == 1) {
                    inertiaString.append("ITR_NEUTRAL ").append(inertia.get(0)).append(System.lineSeparator());
                    continue;
                }
                inertiaString.append("IGEAR ").append(i - 1).append(System.lineSeparator());
                inertiaString.append("ITR ").append(inertia.get(i)).append(System.lineSeparator());
                inertiaString.append("*ITR(").append(i - 1).append(") ").append(inertia.get(i)).append(System.lineSeparator());
            }

            final String drivingJson = vehiclePO.getDrivingJson();
            final List<String> driving;
            if (CollectionUtil.isNotEmpty(vehiclePO.getDriving())) {
                driving = vehiclePO.getDriving();
            } else {
                driving = JsonUtil.jsonToList(drivingJson, String.class);
            }
            StringBuilder drivingString = new StringBuilder();
            for (int i = 0; i < driving.size(); i++) {
                if (i == 0) {
                    drivingString.append("R_EFF_TR_F_REVERSE ").append(driving.get(0)).append(System.lineSeparator());
                    continue;
                }
                if (i == 1) {
                    continue;
                }
                drivingString.append("IGEAR ").append(i - 1).append(System.lineSeparator());
                drivingString.append("R_EFF_TR_F ").append(driving.get(i)).append(System.lineSeparator());
                drivingString.append("*R_EFF_TR_F(").append(i - 1).append(") ").append(driving.get(i)).append(System.lineSeparator());
            }
            final String coastingJson = vehiclePO.getCoastingJson();
            final List<String> coasting;
            if (CollectionUtil.isNotEmpty(vehiclePO.getCoasting())) {
                coasting = vehiclePO.getCoasting();
            } else {
                coasting = JsonUtil.jsonToList(coastingJson, String.class);
            }
            StringBuilder coastingString = new StringBuilder();
            for (int i = 0; i < coasting.size(); i++) {
                if (i == 0) {
                    coastingString.append("R_EFF_TR_R_REVERSE ").append(coasting.get(0)).append(System.lineSeparator());
                    continue;
                }
                if (i == 1) {
                    continue;
                }
                coastingString.append("IGEAR ").append(i - 1).append(System.lineSeparator());
                coastingString.append("R_EFF_TR_R ").append(coasting.get(i)).append(System.lineSeparator());
                coastingString.append("*R_EFF_TR_R(").append(i - 1).append(") ").append(coasting.get(i)).append(System.lineSeparator());
            }
            String parFileName = StringUtil.getRandomEightBitUUID() + ".par";
            String localParFilePath = parTemp + parFileName;
            String minioParFilePath = "/model/" + parFileName;
            FileUtil.writeStringToLocalFile(
                    par.replaceAll("wheelCenterToTop", vehiclePO.getWheelCenterToTop())
                            .replaceAll("wheelCenterToGround", vehiclePO.getWheelCenterToGround())
                            .replaceAll("centroidToFrontWheelCenter", vehiclePO.getCentroidToFrontWheelCenter())
                            .replaceAll("centroidToGround", vehiclePO.getCentroidToGround())
                            .replaceAll("wheelbase", vehiclePO.getWheelbase().toString())
                            .replaceAll("sprungMass", vehiclePO.getSprungMass())
                            .replaceAll("vehicleLength", vehiclePO.getVehicleLength())
                            .replaceAll("vehicleWidth", vehiclePO.getVehicleWidth())
                            .replaceAll("rotationalInertiaX", vehiclePO.getRotationalInertiaX())
                            .replaceAll("rotationalInertiaY", vehiclePO.getRotationalInertiaY())
                            .replaceAll("effectiveRollingRadius", vehiclePO.getFrontLeftWheelEffectiveRollingRadius())
                            .replaceAll("rollingResistanceCoefficient", vehiclePO.getFrontLeftWheelRollingResistanceCoefficient())
                            .replaceAll("freeRadius", vehiclePO.getFrontLeftWheelFreeRadius())
                            .replaceAll("relationCurvePositiveMomentAndSideslipAngle", convertArrayToTableWithoutHead(vehiclePO.getFrontLeftWheelRelationCurvePositiveMomentAndSideslipAngle()))
                            .replaceAll("relationCurveLateralForceAndSideslipAngle", convertArrayToTableWithoutHead(vehiclePO.getFrontLeftWheelRelationCurveLateralForceAndSideslipAngle()))
                            .replaceAll("relationCurveLongitudinalForceAndSideslipAngle", convertArrayToTableWithoutHead(vehiclePO.getFrontLeftWheelRelationCurveLongitudinalForceAndSideslipAngle()))
                            .replaceAll("frontWheelSuspensionKinematicsCoefficient", vehiclePO.getFrontWheelSuspensionKinematicsCoefficient())
                            .replaceAll("rearWheelSuspensionKinematicsCoefficient", vehiclePO.getRearWheelSuspensionKinematicsCoefficient())
                            .replaceAll("rearWheelUnsprungMass", vehiclePO.getRearWheelUnsprungMass())
                            .replaceAll("frontWheelTrackWidth", vehiclePO.getFrontWheelTrackWidth())
                            .replaceAll("rearWheelTrackWidth", vehiclePO.getRearWheelTrackWidth())
                            .replaceAll("windwardArea", vehiclePO.getWindwardArea())
                            .replaceAll("airDensity", vehiclePO.getAirDensity())
                            .replaceAll("engineCrankshaftMomentInertia", vehiclePO.getEngineCrankshaftMomentInertia())
                            .replaceAll("idleSpeed", vehiclePO.getIdleSpeed())
                            .replaceAll("relationCurveEngineTorqueSpeedAndThrottleOpening", convertArrayToTableWithoutHead(vehiclePO.getRelationCurveEngineTorqueSpeedAndThrottleOpening()))
                            .replaceAll("momentInertiaInputShaft", vehiclePO.getMomentInertiaInputShaft())
                            .replaceAll("momentInertiaOutputShaft", vehiclePO.getMomentInertiaOutputShaft())
                            .replaceAll("finalDriveRatio", vehiclePO.getFinalDriveRatio())
                            .replaceAll("transmissionEfficiency", vehiclePO.getTransmissionEfficiency())
                            .replaceAll("gearRatio", gearRatioString.toString())
                            .replaceAll("inertia", inertiaString.toString())
                            .replaceAll("driving", drivingString.toString())
                            .replaceAll("coasting", coastingString.toString())
                            .replace("shiftTimeSource", vehiclePO.getShiftTime()) // 换第一个
                            .replaceAll("shiftTimeUp12", convertArrayToTableWithoutHead(vehiclePO.getShiftTimeUp12()))
                            .replaceAll("shiftTimeDown12", convertArrayToTableWithoutHead(vehiclePO.getShiftTimeDown12()))
                            .replaceAll("shiftTimeUp23", convertArrayToTableWithoutHead(vehiclePO.getShiftTimeUp23()))
                            .replaceAll("shiftTimeDown23", convertArrayToTableWithoutHead(vehiclePO.getShiftTimeDown23()))
                            .replaceAll("shiftTimeUp34", convertArrayToTableWithoutHead(vehiclePO.getShiftTimeUp34()))
                            .replaceAll("shiftTimeDown34", convertArrayToTableWithoutHead(vehiclePO.getShiftTimeDown34()))
                            .replaceAll("shiftTimeUp45", convertArrayToTableWithoutHead(vehiclePO.getShiftTimeUp45()))
                            .replaceAll("shiftTimeDown45", convertArrayToTableWithoutHead(vehiclePO.getShiftTimeDown45()))
                            .replaceAll("shiftTimeUp56", convertArrayToTableWithoutHead(vehiclePO.getShiftTimeUp56()))
                            .replaceAll("shiftTimeDown56", convertArrayToTableWithoutHead(vehiclePO.getShiftTimeDown56())) // 制动力矩不再区分左右，前轮使用前左，后轮使用后左
                            .replaceAll("frontLeftWheelBrakingTorque", vehiclePO.getFrontLeftWheelBrakingTorque())
                            .replaceAll("frontRightWheelBrakingTorque", vehiclePO.getFrontLeftWheelBrakingTorque())
                            .replaceAll("rearLeftWheelBrakingTorque", vehiclePO.getRearLeftWheelBrakingTorque())
                            .replaceAll("rearRightWheelBrakingTorque", vehiclePO.getRearLeftWheelBrakingTorque())
                            .replaceAll("steeringGearRatio", vehiclePO.getSteeringGearRatio())
                            .replaceAll("relationCurveRightWheelAngleAndSteeringGearOutput", convertArrayToTableWithoutHead(vehiclePO.getRelationCurveRightWheelAngleAndSteeringGearOutput()))
                            .replaceAll("relationCurveLeftWheelAngleAndSteeringGearOutput", convertArrayToTableWithoutHead(vehiclePO.getRelationCurveLeftWheelAngleAndSteeringGearOutput()))
                    , localParFilePath);
            fileDownService.uploadLocalFile(localParFilePath, minioParFilePath);
            vehiclePO.setParFilePath(minioParFilePath);
        }
        if (ObjectUtil.isNull(id)) {//新增
            vehiclePO.setId(StringUtil.getRandomUUID());
            vehiclePO.setVehicleCode(StringUtil.getRandomCode());
            vehicleMapper.insert(vehiclePO);
            LogUtil.insert();
        } else {//修改
            vehicleMapper.update(vehiclePO);
            LogUtil.update();
        }
        return vehiclePO;

    }

    public VehiclePO shareVehicle(VehicleVO vehicleVO) {
        //调用保存
        vehicleVO.setSaveOrShare("1");
        VehiclePO vehiclePO = saveVehicle(vehicleVO);
        vehiclePO.setShare(DictConstants.YES);//转公有
        vehiclePO.setCreateUserId(null);
        //名称校验
        List<VehicleVO> list = vehicleMapper.checkVehicleName(vehiclePO);
        String parameterType = vehicleVO.getParameterType();
        if ("2".equals(parameterType)) {
            VehicleUtil.listToJson(vehiclePO);
        }
        if (ObjectUtil.isNotNull(list)) { // 覆盖
            String id = list.get(0).getId();
            vehiclePO.setId(id);
            String currentUserId = AuthUtil.getCurrentUserId();
            Timestamp currentTime = TimeUtil.getNowForMysql();
            vehiclePO.setModifyUserId(currentUserId);
            vehiclePO.setModifyTime(currentTime);
            String sourceParFilePath = vehiclePO.getParFilePath();
            String targetParFilePath = "/model/" + StringUtil.getRandomEightBitUUID() + ".par";
            fileDownService.move(sourceParFilePath, targetParFilePath);
            vehiclePO.setParFilePath(targetParFilePath);
            vehicleMapper.update(vehiclePO);
            LogUtil.update();
        } else { // 新增
            //常规字段赋值
            String currentUserId = AuthUtil.getCurrentUserId();
            Timestamp currentTime = TimeUtil.getNowForMysql();
            vehiclePO.setCreateUserId(currentUserId);
            vehiclePO.setCreateTime(currentTime);
            vehiclePO.setModifyUserId(currentUserId);
            vehiclePO.setModifyTime(currentTime);
            vehiclePO.setIsDeleted(DictConstants.NO);
            vehiclePO.setId(StringUtil.getRandomUUID());
            vehiclePO.setVehicleCode(StringUtil.getRandomCode());
            String sourceParFilePath = vehiclePO.getParFilePath();
            String targetParFilePath = "/model/" + StringUtil.getRandomEightBitUUID() + ".par";
            fileDownService.move(sourceParFilePath, targetParFilePath);
            vehiclePO.setParFilePath(targetParFilePath);
            vehicleMapper.insert(vehiclePO);
        }
        LogUtil.share();
        return vehiclePO;
    }


    public VehicleVO parsePar(String par) {

        try {
            String wheelCenterToTop = par.substring(par.indexOf("HT_SM")).split("\\s")[1];
            String wheelCenterToGround = par.substring(par.indexOf("HWC_LF")).split("\\s")[1];
            String centroidToFrontWheelCenter = par.substring(par.indexOf("LX_CG_SU")).split("\\s")[1];
            String centroidToGround = par.substring(par.indexOf("H_CG_SU")).split("\\s")[1];
            String wheelbase = par.substring(par.indexOf("LX_AXLE")).split("\\s")[1];
            String sprungMass = par.substring(par.indexOf("M_SU")).split("\\s")[1];
            String vehicleLength = par.substring(par.indexOf("LEN_SM")).split("\\s")[1];
            String vehicleWidth = par.substring(par.indexOf("WID_SM")).split("\\s")[1];
            String rotationalInertiaX = par.substring(par.indexOf("IXX_SU")).split("\\s")[1];
            String rotationalInertiaY = par.substring(par.indexOf("IYY_SU")).split("\\s")[1];
            String rotationalInertiaZ = par.substring(par.indexOf("IZZ_SU")).split("\\s")[1];
            String rreAll = par.substring(par.indexOf("*SET_THICKNESS"), par.indexOf("R0"));
            String effectiveRollingRadius = rreAll.substring(rreAll.indexOf("RRE")).split("\\s")[1];
            String freeRadius = par.substring(par.indexOf("R0")).split("\\s")[1];
            String rollingResistanceCoefficient = par.substring(par.indexOf("RR_C")).split("\\s")[1];
            List<List<String>> relationCurvePositiveMomentAndSideslipAngle = convertTableToArray(par.substring(par.indexOf("MZ_TIRE_CARPET 2D_FROM_ZERO")).split("ENDTABLE")[0].replace("MZ_TIRE_CARPET 2D_FROM_ZERO" + System.lineSeparator(), ""));
            String relationCurvePositiveMomentAndSideslipAngleJson = JsonUtil.listToJson(relationCurvePositiveMomentAndSideslipAngle);
            List<List<String>> relationCurveLateralForceAndSideslipAngle = convertTableToArray(par.substring(par.indexOf("FY_TIRE_CARPET 2D_FROM_ZERO")).split("ENDTABLE")[0].replace("FY_TIRE_CARPET 2D_FROM_ZERO" + System.lineSeparator(), ""));
            String relationCurveLateralForceAndSideslipAngleJson = JsonUtil.listToJson(relationCurveLateralForceAndSideslipAngle);
            List<List<String>> relationCurveLongitudinalForceAndSideslipAngle = convertTableToArray(par.substring(par.indexOf("FX_TIRE_CARPET 2D_FROM_ZERO")).split("ENDTABLE")[0].replace("FX_TIRE_CARPET 2D_FROM_ZERO" + System.lineSeparator(), ""));
            String relationCurveLongitudinalForceAndSideslipAngleJson = JsonUtil.listToJson(relationCurveLongitudinalForceAndSideslipAngle);
            String frontWheelSuspensionKinematicsCoefficient = par.substring(par.indexOf("R_US_STR")).split("\\s")[1];
            String rearWheelSuspensionKinematicsCoefficient = par.substring(par.lastIndexOf("R_US_STR")).split("\\s")[1];
            String frontWheelUnsprungMassAll = par.substring(par.indexOf("#FullDataName Suspension: Independent System Kinematics`C-Class, Hatchback - Front`C-Class"));
            String frontWheelUnsprungMass = frontWheelUnsprungMassAll.substring(frontWheelUnsprungMassAll.indexOf("M_US")).split("\\s")[1];
            String rearWheelUnsprungMassAll = par.substring(par.indexOf("#FullDataName Suspension: Independent System Kinematics`C-Class, Hatchback - Rear`C-Class"));
            String rearWheelUnsprungMass = rearWheelUnsprungMassAll.substring(rearWheelUnsprungMassAll.lastIndexOf("M_US")).split("\\s")[1];
            String frontWheelTrackWidth = par.substring(par.indexOf("L_TRACK")).split("\\s")[1];
            String rearWheelTrackWidth = par.substring(par.lastIndexOf("L_TRACK")).split("\\s")[1];
            String windwardArea = par.substring(par.indexOf("AREA_AERO")).split("\\s")[1];
            String airDensity = par.substring(par.indexOf("D_AIR")).split("\\s")[1];
            String engineCrankshaftMomentInertia = par.substring(par.indexOf("IENG")).split("\\s")[1];
            String idleSpeed = par.substring(par.indexOf("AV_ENG_IDLE")).split("\\s")[1];
            List<List<String>> relationCurveEngineTorqueSpeedAndThrottleOpening = convertTableToArray(par.substring(par.indexOf("MENGINE_CARPET 2D_LINEAR")).split("ENDTABLE")[0].replace("MENGINE_CARPET 2D_LINEAR" + System.lineSeparator(), ""));
            String relationCurveEngineTorqueSpeedAndThrottleOpeningJson = JsonUtil.listToJson(relationCurveEngineTorqueSpeedAndThrottleOpening);
            String momentInertiaInputShaft = par.substring(par.indexOf("ITC_INPUT_SHAFT")).split("\\s")[1];
            String momentInertiaOutputShaft = par.substring(par.indexOf("ITC_OUTPUT_SHAFT")).split("\\s")[1];
            String finalDriveRatio = par.substring(par.indexOf("R_GEAR_DIFF")).split("\\s")[1];
            String transmissionEfficiency = par.substring(par.indexOf("R_EFF_F_DIFF")).split("\\s")[1];
            List<String> gearRatio = CollectionUtil.createArrayList(
                    par.substring(par.indexOf("R_GEAR_TR_REVERSE")).split("\\s")[1],
                    "",
                    par.substring(par.indexOf("*R_GEAR_TR(1)")).split("\\s")[1],
                    par.substring(par.indexOf("*R_GEAR_TR(2)")).split("\\s")[1],
                    par.substring(par.indexOf("*R_GEAR_TR(3)")).split("\\s")[1],
                    par.substring(par.indexOf("*R_GEAR_TR(4)")).split("\\s")[1],
                    par.substring(par.indexOf("*R_GEAR_TR(5)")).split("\\s")[1],
                    par.substring(par.indexOf("*R_GEAR_TR(6)")).split("\\s")[1]
            );
            String gearRatioJson = JsonUtil.listToJson(gearRatio);//R,N,1,2,3,4,5,6
            List<String> inertia = CollectionUtil.createArrayList(
                    par.substring(par.indexOf("ITR_REVERSE")).split("\\s")[1],
                    par.substring(par.indexOf("ITR_NEUTRAL")).split("\\s")[1],
                    par.substring(par.indexOf("*ITR(1)")).split("\\s")[1],
                    par.substring(par.indexOf("*ITR(2)")).split("\\s")[1],
                    par.substring(par.indexOf("*ITR(3)")).split("\\s")[1],
                    par.substring(par.indexOf("*ITR(4)")).split("\\s")[1],
                    par.substring(par.indexOf("*ITR(5)")).split("\\s")[1],
                    par.substring(par.indexOf("*ITR(6)")).split("\\s")[1]
            );//R,N,1,2,3,4,5,6
            String inertiaJson = JsonUtil.listToJson(inertia);//R,N,1,2,3,4,5,6
            List<String> driving = CollectionUtil.createArrayList(
                    par.substring(par.indexOf("R_EFF_TR_F_REVERSE")).split("\\s")[1],
                    "",
                    par.substring(par.indexOf("*R_EFF_TR_F(1)")).split("\\s")[1],
                    par.substring(par.indexOf("*R_EFF_TR_F(2)")).split("\\s")[1],
                    par.substring(par.indexOf("*R_EFF_TR_F(3)")).split("\\s")[1],
                    par.substring(par.indexOf("*R_EFF_TR_F(4)")).split("\\s")[1],
                    par.substring(par.indexOf("*R_EFF_TR_F(5)")).split("\\s")[1],
                    par.substring(par.indexOf("*R_EFF_TR_F(6)")).split("\\s")[1]
            );//R,N,1,2,3,4,5,6
            String drivingJson = JsonUtil.listToJson(driving);//R,N,1,2,3,4,5,6
            List<String> coasting = CollectionUtil.createArrayList(
                    par.substring(par.indexOf("R_EFF_TR_R_REVERSE")).split("\\s")[1],
                    "",
                    par.substring(par.indexOf("*R_EFF_TR_R(1)")).split("\\s")[1],
                    par.substring(par.indexOf("*R_EFF_TR_R(2)")).split("\\s")[1],
                    par.substring(par.indexOf("*R_EFF_TR_R(3)")).split("\\s")[1],
                    par.substring(par.indexOf("*R_EFF_TR_R(4)")).split("\\s")[1],
                    par.substring(par.indexOf("*R_EFF_TR_R(5)")).split("\\s")[1],
                    par.substring(par.indexOf("*R_EFF_TR_R(6)")).split("\\s")[1]
            );//R,N,1,2,3,4,5,6
            String coastingJson = JsonUtil.listToJson(coasting);//R,N,1,2,3,4,5,6
            String shiftTime = par.substring(par.lastIndexOf("T_SHIFT")).split("\\s")[1];//换挡时间
            String shiftTime12All = par.substring(
                    par.indexOf("#FullDataName Powertrain: Shift Schedule`6-speed, 1-2 Shift`6-speed"),
                    par.indexOf("#DataSet : 6-speed, 1-2 Shift")
            );
            String shiftTime23All = par.substring(
                    par.indexOf("#FullDataName Powertrain: Shift Schedule`6-speed, 2-3 Shift`6-speed"),
                    par.indexOf("#DataSet : 6-speed, 2-3 Shift")
            );
            String shiftTime34All = par.substring(
                    par.indexOf("#FullDataName Powertrain: Shift Schedule`6-speed, 3-4 Shift`6-speed"),
                    par.indexOf("#DataSet : 6-speed, 3-4 Shift")
            );
            String shiftTime45All = par.substring(
                    par.indexOf("#FullDataName Powertrain: Shift Schedule`6-speed, 4-5 Shift`6-speed"),
                    par.indexOf("#DataSet : 6-speed, 4-5 Shift")
            );
            String shiftTime56All = par.substring(
                    par.indexOf("#FullDataName Powertrain: Shift Schedule`6-speed, 5-6 Shift`6-speed"),
                    par.indexOf("#DataSet : 6-speed, 5-6 Shift")
            );
            List<List<String>> shiftTimeUp12 = convertTableToArray(shiftTime12All.substring(shiftTime12All.indexOf("UPSHIFT_TRANS_TABLE")).split("ENDTABLE")[0].replace("UPSHIFT_TRANS_TABLE" + System.lineSeparator(), ""));//
            String shiftTimeUp12Json = JsonUtil.listToJson(shiftTimeUp12);//
            List<List<String>> shiftTimeDown12 = convertTableToArray(shiftTime12All.substring(shiftTime12All.indexOf("DOWNSHIFT_TRANS_TABLE")).split("ENDTABLE")[0].replace("DOWNSHIFT_TRANS_TABLE" + System.lineSeparator(), ""));//
            String shiftTimeDown12Json = JsonUtil.listToJson(shiftTimeDown12);//

            List<List<String>> shiftTimeUp23 = convertTableToArray(shiftTime23All.substring(shiftTime23All.indexOf("UPSHIFT_TRANS_TABLE")).split("ENDTABLE")[0].replace("UPSHIFT_TRANS_TABLE" + System.lineSeparator(), ""));//
            String shiftTimeUp23Json = JsonUtil.listToJson(shiftTimeUp23);//
            List<List<String>> shiftTimeDown23 = convertTableToArray(shiftTime23All.substring(shiftTime23All.indexOf("DOWNSHIFT_TRANS_TABLE")).split("ENDTABLE")[0].replace("DOWNSHIFT_TRANS_TABLE" + System.lineSeparator(), ""));//
            String shiftTimeDown23Json = JsonUtil.listToJson(shiftTimeDown23);//

            List<List<String>> shiftTimeUp34 = convertTableToArray(shiftTime34All.substring(shiftTime34All.indexOf("UPSHIFT_TRANS_TABLE")).split("ENDTABLE")[0].replace("UPSHIFT_TRANS_TABLE" + System.lineSeparator(), ""));//
            String shiftTimeUp34Json = JsonUtil.listToJson(shiftTimeUp34);//
            List<List<String>> shiftTimeDown34 = convertTableToArray(shiftTime34All.substring(shiftTime34All.indexOf("DOWNSHIFT_TRANS_TABLE")).split("ENDTABLE")[0].replace("DOWNSHIFT_TRANS_TABLE" + System.lineSeparator(), ""));//
            String shiftTimeDown34Json = JsonUtil.listToJson(shiftTimeDown34);//

            List<List<String>> shiftTimeUp45 = convertTableToArray(shiftTime45All.substring(shiftTime45All.indexOf("UPSHIFT_TRANS_TABLE")).split("ENDTABLE")[0].replace("UPSHIFT_TRANS_TABLE" + System.lineSeparator(), ""));//
            String shiftTimeUp45Json = JsonUtil.listToJson(shiftTimeUp45);//
            List<List<String>> shiftTimeDown45 = convertTableToArray(shiftTime45All.substring(shiftTime45All.indexOf("DOWNSHIFT_TRANS_TABLE")).split("ENDTABLE")[0].replace("DOWNSHIFT_TRANS_TABLE" + System.lineSeparator(), ""));//
            String shiftTimeDown45Json = JsonUtil.listToJson(shiftTimeDown45);//

            List<List<String>> shiftTimeUp56 = convertTableToArray(shiftTime56All.substring(shiftTime56All.indexOf("UPSHIFT_TRANS_TABLE")).split("ENDTABLE")[0].replace("UPSHIFT_TRANS_TABLE" + System.lineSeparator(), ""));//
            String shiftTimeUp56Json = JsonUtil.listToJson(shiftTimeUp56);//
            List<List<String>> shiftTimeDown56 = convertTableToArray(shiftTime56All.substring(shiftTime56All.indexOf("DOWNSHIFT_TRANS_TABLE")).split("ENDTABLE")[0].replace("DOWNSHIFT_TRANS_TABLE" + System.lineSeparator(), ""));//
            String shiftTimeDown56Json = JsonUtil.listToJson(shiftTimeDown56);//

            String frontBrakingTorque = par.substring(par.indexOf("MY_BRAKE_COEFFICIENT")).split("\\s")[1];
            String rearBrakingTorque = par.substring(par.lastIndexOf("MY_BRAKE_COEFFICIENT")).split("\\s")[1];
            String steeringGearRatio = par.substring(par.lastIndexOf("*CF_F")).split("\\s")[1];

            List<List<String>> relationCurveRightWheelAngleAndSteeringGearOutput = convertTableToArray(par.substring(par.indexOf("RACK_KIN_TABLE SPLINE")).split("ENDTABLE")[0].replace("RACK_KIN_TABLE SPLINE" + System.lineSeparator(), ""));//
            String relationCurveRightWheelAngleAndSteeringGearOutputJson = JsonUtil.listToJson(relationCurveRightWheelAngleAndSteeringGearOutput);//
            List<List<String>> relationCurveLeftWheelAngleAndSteeringGearOutput = convertTableToArray(par.substring(par.lastIndexOf("RACK_KIN_TABLE SPLINE")).split("ENDTABLE")[0].replace("RACK_KIN_TABLE SPLINE" + System.lineSeparator(), ""));//
            String relationCurveLeftWheelAngleAndSteeringGearOutputJson = JsonUtil.listToJson(relationCurveLeftWheelAngleAndSteeringGearOutput);//


            return VehicleVO.builder()
                    .wheelCenterToTop(wheelCenterToTop)
                    .wheelCenterToGround(wheelCenterToGround)
                    .centroidToFrontWheelCenter(centroidToFrontWheelCenter)
                    .centroidToGround(centroidToGround)
                    .wheelbase(new BigDecimal(wheelbase))
                    .sprungMass(sprungMass)
                    .vehicleLength(vehicleLength)
                    .vehicleWidth(vehicleWidth)
                    .rotationalInertiaX(rotationalInertiaX)
                    .rotationalInertiaY(rotationalInertiaY)
                    .rotationalInertiaZ(rotationalInertiaZ)
                    .frontLeftWheelEffectiveRollingRadius(effectiveRollingRadius)
                    .frontRightWheelEffectiveRollingRadius(effectiveRollingRadius)
                    .rearLeftWheelEffectiveRollingRadius(effectiveRollingRadius)
                    .rearRightWheelEffectiveRollingRadius(effectiveRollingRadius)
                    .frontLeftWheelRollingResistanceCoefficient(rollingResistanceCoefficient)
                    .frontRightWheelRollingResistanceCoefficient(rollingResistanceCoefficient)
                    .rearLeftWheelRollingResistanceCoefficient(rollingResistanceCoefficient)
                    .rearRightWheelRollingResistanceCoefficient(rollingResistanceCoefficient)
                    .frontLeftWheelFreeRadius(freeRadius)
                    .frontRightWheelFreeRadius(freeRadius)
                    .rearLeftWheelFreeRadius(freeRadius)
                    .rearRightWheelFreeRadius(freeRadius)
                    .frontLeftWheelRelationCurvePositiveMomentAndSideslipAngle(relationCurvePositiveMomentAndSideslipAngle)
                    .frontLeftWheelRelationCurvePositiveMomentAndSideslipAngleJson(relationCurvePositiveMomentAndSideslipAngleJson)
                    .frontRightWheelRelationCurvePositiveMomentAndSideslipAngle(relationCurvePositiveMomentAndSideslipAngle)
                    .frontRightWheelRelationCurvePositiveMomentAndSideslipAngleJson(relationCurvePositiveMomentAndSideslipAngleJson)
                    .rearLeftWheelRelationCurvePositiveMomentAndSideslipAngle(relationCurvePositiveMomentAndSideslipAngle)
                    .rearLeftWheelRelationCurvePositiveMomentAndSideslipAngleJson(relationCurvePositiveMomentAndSideslipAngleJson)
                    .rearRightWheelRelationCurvePositiveMomentAndSideslipAngle(relationCurvePositiveMomentAndSideslipAngle)
                    .rearRightWheelRelationCurvePositiveMomentAndSideslipAngleJson(relationCurvePositiveMomentAndSideslipAngleJson)
                    .frontLeftWheelRelationCurveLateralForceAndSideslipAngle(relationCurveLateralForceAndSideslipAngle)
                    .frontLeftWheelRelationCurveLateralForceAndSideslipAngleJson(relationCurveLateralForceAndSideslipAngleJson)
                    .frontRightWheelRelationCurveLateralForceAndSideslipAngle(relationCurveLateralForceAndSideslipAngle)
                    .frontRightWheelRelationCurveLateralForceAndSideslipAngleJson(relationCurveLateralForceAndSideslipAngleJson)
                    .rearLeftWheelRelationCurveLateralForceAndSideslipAngle(relationCurveLateralForceAndSideslipAngle)
                    .rearLeftWheelRelationCurveLateralForceAndSideslipAngleJson(relationCurveLateralForceAndSideslipAngleJson)
                    .rearRightWheelRelationCurveLateralForceAndSideslipAngle(relationCurveLateralForceAndSideslipAngle)
                    .rearRightWheelRelationCurveLateralForceAndSideslipAngleJson(relationCurveLateralForceAndSideslipAngleJson)
                    .frontLeftWheelRelationCurveLongitudinalForceAndSideslipAngle(relationCurveLongitudinalForceAndSideslipAngle)
                    .frontLeftWheelRelationCurveLongitudinalForceAndSideslipAngleJson(relationCurveLongitudinalForceAndSideslipAngleJson)
                    .frontRightWheelRelationCurveLongitudinalForceAndSideslipAngle(relationCurveLongitudinalForceAndSideslipAngle)
                    .frontRightWheelRelationCurveLongitudinalForceAndSideslipAngleJson(relationCurveLongitudinalForceAndSideslipAngleJson)
                    .rearLeftWheelRelationCurveLongitudinalForceAndSideslipAngle(relationCurveLongitudinalForceAndSideslipAngle)
                    .rearLeftWheelRelationCurveLongitudinalForceAndSideslipAngleJson(relationCurveLongitudinalForceAndSideslipAngleJson)
                    .rearRightWheelRelationCurveLongitudinalForceAndSideslipAngle(relationCurveLongitudinalForceAndSideslipAngle)
                    .rearRightWheelRelationCurveLongitudinalForceAndSideslipAngleJson(relationCurveLongitudinalForceAndSideslipAngleJson)
                    .frontWheelSuspensionType("1")  //TODO  目前只使用独立悬架
                    .rearWheelSuspensionType("1")   //TODO  目前只使用独立悬架
                    .frontWheelSuspensionKinematicsCoefficient(frontWheelSuspensionKinematicsCoefficient)
                    .rearWheelSuspensionKinematicsCoefficient(rearWheelSuspensionKinematicsCoefficient)
                    .frontWheelUnsprungMass(frontWheelUnsprungMass)
                    .rearWheelUnsprungMass(rearWheelUnsprungMass)
                    .frontWheelTrackWidth(frontWheelTrackWidth)
                    .rearWheelTrackWidth(rearWheelTrackWidth)
                    .windwardArea(windwardArea)
                    .airDensity(airDensity)
                    .engineCrankshaftMomentInertia(engineCrankshaftMomentInertia)
                    .idleSpeed(idleSpeed)
                    .relationCurveEngineTorqueSpeedAndThrottleOpening(relationCurveEngineTorqueSpeedAndThrottleOpening)
                    .relationCurveEngineTorqueSpeedAndThrottleOpeningJson(relationCurveEngineTorqueSpeedAndThrottleOpeningJson)
                    .momentInertiaInputShaft(momentInertiaInputShaft)
                    .momentInertiaOutputShaft(momentInertiaOutputShaft)
                    .finalDriveRatio(finalDriveRatio)
                    .transmissionEfficiency(transmissionEfficiency)
                    .gearRatio(gearRatio)
                    .gearRatioJson(gearRatioJson)
                    .inertia(inertia)
                    .inertiaJson(inertiaJson)
                    .driving(driving)
                    .drivingJson(drivingJson)
                    .coasting(coasting)
                    .coastingJson(coastingJson)
                    .shiftTime(shiftTime)
                    .shiftTimeUp12(shiftTimeUp12)
                    .shiftTimeUp12Json(shiftTimeUp12Json)
                    .shiftTimeDown12(shiftTimeDown12)
                    .shiftTimeDown12Json(shiftTimeDown12Json)

                    .shiftTimeUp23(shiftTimeUp23)
                    .shiftTimeUp23Json(shiftTimeUp23Json)
                    .shiftTimeDown23(shiftTimeDown23)
                    .shiftTimeDown23Json(shiftTimeDown23Json)

                    .shiftTimeUp34(shiftTimeUp34)
                    .shiftTimeUp34Json(shiftTimeUp34Json)
                    .shiftTimeDown34(shiftTimeDown34)
                    .shiftTimeDown34Json(shiftTimeDown34Json)

                    .shiftTimeUp45(shiftTimeUp45)
                    .shiftTimeUp45Json(shiftTimeUp45Json)
                    .shiftTimeDown45(shiftTimeDown45)
                    .shiftTimeDown45Json(shiftTimeDown45Json)

                    .shiftTimeUp56(shiftTimeUp56)
                    .shiftTimeUp56Json(shiftTimeUp56Json)
                    .shiftTimeDown56(shiftTimeDown56)
                    .shiftTimeDown56Json(shiftTimeDown56Json)
//                    .brakeType("1")   暂时不要制动类型
                    .frontLeftWheelBrakingTorque(frontBrakingTorque)
                    .frontRightWheelBrakingTorque(frontBrakingTorque)
                    .rearLeftWheelBrakingTorque(rearBrakingTorque)
                    .rearRightWheelBrakingTorque(rearBrakingTorque)
                    .steeringType("1")  //TODO  暂时只用前轮转向
                    .steeringGearType("1")  //TODO  暂时只用齿轮齿条转向器
                    .steeringGearRatio(steeringGearRatio)
                    .relationCurveRightWheelAngleAndSteeringGearOutput(relationCurveRightWheelAngleAndSteeringGearOutput)
                    .relationCurveRightWheelAngleAndSteeringGearOutputJson(relationCurveRightWheelAngleAndSteeringGearOutputJson)
                    .relationCurveLeftWheelAngleAndSteeringGearOutput(relationCurveLeftWheelAngleAndSteeringGearOutput)
                    .relationCurveLeftWheelAngleAndSteeringGearOutputJson(relationCurveLeftWheelAngleAndSteeringGearOutputJson)
                    .driverType("1")    //TODO 暂时只用前轮驱动
                    .build();
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }


    public List<List<String>> convertTableToArray(String table) {
        List<List<String>> result = new ArrayList<>();

        //1 判断有几列生成表头
        String[] lines = StringUtil.splitByLineSeparator(table);
        int columnCount = lines[1].replaceAll(" ", "").split(",").length;
        List<String> headList;
        if (columnCount == 2) {
            headList = CollectionUtil.createArrayList("X Axis", "Y Axis");
        } else if (columnCount > 2) {
            headList = CollectionUtil.createArrayList("X Axis");
            for (int i = 1; i <= columnCount - 1; i++) {
                headList.add(String.valueOf(i));
            }
        } else {
            throw new RuntimeException("列数不能小于2");
        }
        result.add(headList);
        for (int i = 1; i < lines.length; i++) {
            String lineWithoutBlank = lines[i].replaceAll(" ", "");
            String[] split = lineWithoutBlank.split(",");
            result.add(Arrays.asList(split));
        }
        return result;
    }

    public String convertArrayToTable(List<List<String>> lines) {
        //1 判断有几列生成表头
        List<String> headList;
        int columnCount = lines.get(0).size();
        if (columnCount == 2) {
            headList = CollectionUtil.createArrayList("X Axis", "Y Axis");
        } else {
            headList = CollectionUtil.createArrayList("X Axis");
            for (int i = 1; i <= columnCount - 1; i++) {
                headList.add(String.valueOf(i));
            }
        }
        //2 第一行换成表头
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("X Axis");
        for (int i = 1; i < headList.size(); i++) {
            stringBuilder.append(",").append(headList.get(i));
        }
        stringBuilder.append(System.lineSeparator());
        for (int i = 1; i < lines.size(); i++) {
            List<String> words = lines.get(i);
            stringBuilder.append(words.get(0));
            for (int j = 1; i < words.size(); i++) {
                stringBuilder.append(",").append(words.get(j));
            }
            if (i != lines.size() - 1) {
                stringBuilder.append(System.lineSeparator());
            }
        }
        return stringBuilder.toString();
    }

    public String convertArrayToTableWithoutHead(List<List<String>> lines) {
        if (CollectionUtil.isEmpty(lines)) {
            return "";
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 1; i < lines.size(); i++) {
            List<String> words = lines.get(i);
            stringBuilder.append(words.get(0));
            for (int j = 1; j < words.size(); j++) {
                stringBuilder.append(",").append(words.get(j));
            }
            if (i != lines.size() - 1) {
                stringBuilder.append(System.lineSeparator());
            }
        }
        return stringBuilder.toString();
    }

//    /**
//     * 将本地文件转成MultipartFile
//     *
//     * @param path
//     * @return
//     */
//    public static MultipartFile toMultipartFile(String path) {
//        //先将本地文件转化成FileItem
//        FileItem fileItem = createFileItem(path);
//        return new CommonsMultipartFile(fileItem);
//    }
//
//    /**
//     * 根据filePath将puppeteer截取到的图片转成FileItem
//     *
//     * @param filePath 文件路径
//     * @return
//     */
//    public static FileItem createFileItem(String filePath) {
//        FileItem item = new DiskFileItemFactory().createItem("file", MediaType.MULTIPART_FORM_DATA_VALUE, true, file.getName());
//        try (InputStream input = new FileInputStream(file);
//             OutputStream os = item.getOutputStream()) {
//            // 流转移
//            IOUtils.copy(input, os);
//        } catch (Exception e) {
//            throw new IllegalArgumentException("Invalid file: " + e, e);
//        }
//
//        return new CommonsMultipartFile(item);
//    }


    //新增共有、私有
    public List<VehicleGSVO> getMyVehicleListNew() {
        List<VehicleVO> listGy = vehicleMapper.selectPrivateAndPublicByCreateUserIdGy(AuthUtil.getCurrentUserId());
        List<VehicleVO> listSy = vehicleMapper.selectPrivateAndPublicByCreateUserIdSy(AuthUtil.getCurrentUserId());
        List<VehicleGSVO> listAll = new ArrayList<>();
        VehicleGSVO vo = new VehicleGSVO();
        vo.setLabel("公有");
        vo.setOptions(listGy);
        VehicleGSVO vo1 = new VehicleGSVO();
        vo1.setLabel("私有");
        vo1.setOptions(listSy);
        listAll.add(vo1);
        listAll.add(vo);
        return listAll;
    }

    //新增共有、私有
    public List getMyVehicleListNew1() {
        List<Map> treeList = new ArrayList<>();
        List<VehicleVO> listGy = vehicleMapper.selectPrivateAndPublicByCreateUserIdGy(AuthUtil.getCurrentUserId());
        List<VehicleVO> listSy = vehicleMapper.selectPrivateAndPublicByCreateUserIdSy(AuthUtil.getCurrentUserId());
        Map typeMap = new HashMap();
        typeMap.put("code", "公有");
        typeMap.put("name", "公有");
        List<Map> colourList = new LinkedList();
        listGy.forEach(vo -> {
            Map colourMap = new HashMap();
            colourMap.put("code", vo.getId());
            colourMap.put("name", vo.getVehicleName());
            colourMap.put("vo", vo);
            colourList.add(colourMap);
        });
        typeMap.put("children", colourList);
        Map typeMap1 = new HashMap();
        typeMap1.put("code", "私有");
        typeMap1.put("name", "私有");
        List<Map> colourList1 = new LinkedList();
        listSy.forEach(vo -> {
            Map colourMap = new HashMap();
            colourMap.put("code", vo.getId());
            colourMap.put("name", vo.getVehicleName());
            colourMap.put("vo", vo);
            colourList1.add(colourMap);
        });
        typeMap1.put("children", colourList1);
        treeList.add(typeMap);
        treeList.add(typeMap1);
        return treeList;
    }
}
