package com.muyu.iotDB.service.impl;

import com.muyu.iotDB.config.IotDBSessionConfig;
import com.muyu.iotDB.data.IotDbParam;
import com.muyu.iotDB.data.IotDbResult;

import com.muyu.iotDB.service.IotDbServer;
import com.muyu.mqtt.dao.MessageData;
import lombok.extern.log4j.Log4j2;
import org.apache.iotdb.rpc.IoTDBConnectionException;
import org.apache.iotdb.rpc.StatementExecutionException;
import org.apache.iotdb.session.SessionDataSet;
import org.apache.iotdb.tsfile.read.common.Field;
import org.apache.iotdb.tsfile.read.common.RowRecord;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.rmi.ServerException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * description: iot服务实现类
 * date: 2022/8/15 9:43
 * author: zhouhong
 */

@Log4j2
@Service
public class IotDbServerImpl implements IotDbServer {

    @Resource
    private IotDBSessionConfig iotDBSessionConfig;

    @Override
    public void insertData(IotDbParam iotDbParam) throws ServerException, IoTDBConnectionException, StatementExecutionException {
        // iotDbParam: 模拟设备上报消息
        // bizkey: 业务唯一key  PK :产品唯一编码   SN:设备唯一编码
        String deviceId = "root.bizkey."+ iotDbParam.getPk() + "." + iotDbParam.getSn();
        // 将设备上报的数据存入数据库(时序数据库)
        List<String> measurementsList = new ArrayList<>();
        measurementsList.add("heart");
        measurementsList.add("breath");
        List<String> valuesList = new ArrayList<>();
        valuesList.add(String.valueOf(iotDbParam.getHeart()));
        valuesList.add(String.valueOf(iotDbParam.getBreath()));
        iotDBSessionConfig.insertRecord(deviceId, iotDbParam.getTime(), measurementsList, valuesList);
    }

    @Override
    public List<IotDbResult> queryDataFromIotDb(IotDbParam iotDbParam) throws Exception {
        List<IotDbResult> iotDbResultList = new ArrayList<>();

        if (null != iotDbParam.getPk() && null != iotDbParam.getSn()) {
            String sql = "select * from root.bizkey."+ iotDbParam.getPk() +"." + iotDbParam.getSn() + " where time >= "
                    + iotDbParam.getStartTime() + " and time < " + iotDbParam.getEndTime();
            SessionDataSet sessionDataSet = iotDBSessionConfig.query(sql);
            List<String> columnNames = sessionDataSet.getColumnNames();
            List<String> titleList = new ArrayList<>();
            // 排除Time字段 -- 方便后面后面拼装数据
            for (int i = 1; i < columnNames.size(); i++) {
                String[] temp = columnNames.get(i).split("\\.");
                titleList.add(temp[temp.length - 1]);
            }
            // 封装处理数据
            packagingData(iotDbParam, iotDbResultList, sessionDataSet, titleList);
        } else {
            log.info("PK或者SN不能为空！！");
        }
        return iotDbResultList;
    }

    @Override
    public void add(MessageData messageData) throws ServerException, IoTDBConnectionException, StatementExecutionException {

        String deviceId = "root.bizkey."+ messageData.getVin();
        // 将设备上报的数据存入数据库(时序数据库)
        List<String> measurementsList = new ArrayList<>();
        measurementsList.add("vin");
        measurementsList.add("getTimestamp");
        measurementsList.add("longitude");
        measurementsList.add("latitude");
        measurementsList.add("speed");
        measurementsList.add("mileage");
        measurementsList.add("dischargeVoltage");
        measurementsList.add("dischargeCurrent");
        measurementsList.add("insulationResistance");
        measurementsList.add("gear");
        measurementsList.add("accelerationPedal");
        measurementsList.add("brakePedal");
        measurementsList.add("fuelConsumption");
        measurementsList.add("motorControllerTemperature");
        measurementsList.add("motorSpeed");
        measurementsList.add("motorTorque");
        measurementsList.add("motorTemperature");
        measurementsList.add("motorVoltage");
        measurementsList.add("motorCurrent");
        measurementsList.add("powerBattery");
        measurementsList.add("maxFeedbackPower");
        measurementsList.add("maxDischargePower");
        measurementsList.add("bmsSelfCheck");
        measurementsList.add("powerBatteryCurrent");
        measurementsList.add("powerBatteryV3");
        measurementsList.add("maxVoltage");
        measurementsList.add("minVoltage");
        measurementsList.add("maxTemperature");
        measurementsList.add("minTemperature");
        measurementsList.add("availableCapacity");
        measurementsList.add("vehicleStatus");
        measurementsList.add("chargeStatus");
        measurementsList.add("runStatus");
        measurementsList.add("soc");
        measurementsList.add("chargeWorkStatus");
        measurementsList.add("driveMotorStatus");
        measurementsList.add("location");
        measurementsList.add("eas");
        measurementsList.add("ptc");
        measurementsList.add("eps");
        measurementsList.add("abs");
        measurementsList.add("mcu");
        measurementsList.add("powerBatteryHeating");
        measurementsList.add("powerBatteryCurrentStatus");
        measurementsList.add("powerBatteryHeat");
        measurementsList.add("dcdc");
        measurementsList.add("chg");
        List<String> valuesList = new ArrayList<>();
       valuesList.add(messageData.getVin());
       valuesList.add(messageData.getTimestamp());
       valuesList.add(messageData.getLongitude());
       valuesList.add(messageData.getLatitude());
       valuesList.add(messageData.getSpeed());
       valuesList.add(messageData.getMileage());
       valuesList.add(messageData.getDischargeVoltage());
       valuesList.add(messageData.getDischargeCurrent());
       valuesList.add(messageData.getInsulationResistance());
       valuesList.add(messageData.getGear());
       valuesList.add(messageData.getAccelerationPedal());
       valuesList.add(messageData.getBrakePedal());
       valuesList.add(messageData.getFuelConsumption());
       valuesList.add(messageData.getMotorControllerTemperature());
       valuesList.add(messageData.getMotorSpeed());
       valuesList.add(messageData.getMotorTorque());
       valuesList.add(messageData.getMotorTemperature());
       valuesList.add(messageData.getMotorVoltage());
       valuesList.add(messageData.getMotorCurrent());
       valuesList.add(messageData.getPowerBattery());
       valuesList.add(messageData.getMaxFeedbackPower());
       valuesList.add(messageData.getMaxDischargePower());
       valuesList.add(messageData.getBmsSelfCheck());
       valuesList.add(messageData.getPowerBatteryCurrent());
       valuesList.add(messageData.getPowerBatteryV3());
       valuesList.add(messageData.getMaxVoltage());
       valuesList.add(messageData.getMinVoltage());
       valuesList.add(messageData.getMaxTemperature());
       valuesList.add(messageData.getMinTemperature());
       valuesList.add(messageData.getAvailableCapacity());
       valuesList.add(messageData.getVehicleStatus());
       valuesList.add(messageData.getChargeStatus());
       valuesList.add(messageData.getRunStatus());
       valuesList.add(messageData.getSoc());
       valuesList.add(messageData.getChargeWorkStatus());
       valuesList.add(messageData.getDriveMotorStatus());
       valuesList.add(messageData.getLocation());
       valuesList.add(messageData.getEas());
       valuesList.add(messageData.getPtc());
       valuesList.add(messageData.getEps());
       valuesList.add(messageData.getAbs());
       valuesList.add(messageData.getMcu());
       valuesList.add(messageData.getPowerBatteryHeating());
       valuesList.add(messageData.getPowerBatteryCurrentStatus());
       valuesList.add(messageData.getPowerBatteryHeat());
       valuesList.add(messageData.getDcdc());
       valuesList.add(messageData.getChg());
        iotDBSessionConfig.insertRecord(deviceId, Long.valueOf(messageData.getTimestamp()), measurementsList, valuesList);
    }

    /**
     * 查新vin
     * @param vin
     * @return
     */
    @Override
    public List<MessageData> selectQueryData(String vin) throws IoTDBConnectionException, StatementExecutionException {
//        List<IotDbResult> iotDbResultList = new ArrayList<>();
//
//        if (null !=vin) {
//            String sql = "select * from root.bizkey."+ vin ;
//            SessionDataSet sessionDataSet = iotDBSessionConfig.query(sql);
//            List<String> columnNames = sessionDataSet.getColumnNames();
//            List<String> titleList = new ArrayList<>();
//            // 排除Time字段 -- 方便后面后面拼装数据
//            for (int i = 1; i < columnNames.size(); i++) {
//                String[] temp = columnNames.get(i).split("\\.");
//                titleList.add(temp[temp.length - 1]);
//            }
//            // 封装处理数据
//            packagingData(iotDbParam, iotDbResultList, sessionDataSet, titleList);
//        } else {
//            log.info("PK或者SN不能为空！！");
//        }
//        return iotDbResultList;
//    }    }
        return null;
    }

    /**
     * 封装处理数据
     * @param iotDbParam
     * @param iotDbResultList
     * @param sessionDataSet
     * @param titleList
     * @throws StatementExecutionException
     * @throws IoTDBConnectionException
     */
    private void packagingData(IotDbParam iotDbParam, List<IotDbResult> iotDbResultList, SessionDataSet sessionDataSet, List<String> titleList)
            throws StatementExecutionException, IoTDBConnectionException {
        int fetchSize = sessionDataSet.getFetchSize();
        if (fetchSize > 0) {
            while (sessionDataSet.hasNext()) {
                IotDbResult iotDbResult = new IotDbResult();
                RowRecord next = sessionDataSet.next();
                List<Field> fields = next.getFields();
                String timeString = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(next.getTimestamp());
                iotDbResult.setTime(timeString);
                Map<String, String> map = new HashMap<>();

                for (int i = 0; i < fields.size(); i++) {
                    Field field = fields.get(i);
                    // 这里的需要按照类型获取
                    map.put(titleList.get(i), field.getObjectValue(field.getDataType()).toString());
                }
                iotDbResult.setTime(timeString);
                iotDbResult.setPk(iotDbParam.getPk());
                iotDbResult.setSn(iotDbParam.getSn());
                iotDbResult.setHeart(map.get("heart"));
                iotDbResult.setBreath(map.get("breath"));
                iotDbResultList.add(iotDbResult);
            }
        }
    }
}