
package com.muyu.common.iotdb.config;

import com.alibaba.fastjson2.JSONObject;
import lombok.extern.log4j.Log4j2;
import org.apache.iotdb.isession.SessionDataSet;
import org.apache.iotdb.isession.pool.SessionDataSetWrapper;
import org.apache.iotdb.rpc.IoTDBConnectionException;
import org.apache.iotdb.rpc.StatementExecutionException;
import org.apache.iotdb.session.pool.SessionPool;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.read.common.Field;
import org.apache.iotdb.tsfile.read.common.RowRecord;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.muyu.common.iotdb.constant.IotdbConstant.ROOT_DATA_DATAJSON;
import static com.muyu.common.iotdb.constant.IotdbConstant.SELECT_ROOT_DATA_DATAJSON_DATASOURCE;

/**
 * @Author WangXin
 * @Data 2024/9/30
 * @Description IotDBSessionConfig配置类
 * @Version 1.0.0
 */
@Log4j2
@Component
@Configuration
public class IotDBSessionConfig {

    @Value("${spring.iotdb.username:root}")
    private String username;

    @Value("${spring.iotdb.password:root}")
    private String password;

    @Value("${spring.iotdb.ip:127.0.0.1}")
    private String ip;

    @Value("${spring.iotdb.port:6667}")
    private int port;

    @Value("${spring.iotdb.maxSize:10}")
    private int maxSize;

    private static SessionPool sessionPool;

    /**
     * 获取IotDBSession对象
     * @return iotDBSession对象
     */
    public SessionPool getSessionPool() {
        if (sessionPool == null) {
            sessionPool = new SessionPool(ip, port, username, password, maxSize);
        }
        return sessionPool;
    }

    /**
     * 添加数据
     * @param deviceId
     * @param time
     * @param measurements
     * @param value
     */
    public void insertRecord(SessionPool sessionPool,String deviceId,
                             Long time, List<String> measurements,List<TSDataType> dataTypeList, JSONObject value) {
        try {
            log.info("iotdb数据入库：device_id:[{}], measurements:[{}], values:[{}]", deviceId, measurements, value);
            sessionPool.insertRecord(deviceId, time, measurements,dataTypeList,new Object[]{value.toJSONString()});
        } catch (Exception e) {
            log.error("IotDBSession insertRecord失败: deviceId={}, time={}, measurements={}, values={}, error={}",
                    deviceId, time, measurements, value, e.getMessage());
        }
    }

    public void JSONObject(JSONObject value){

    }

    /**
     * sql查数据
     * @param sessionPool
     * @param sql
     * @return
     */
    public SessionDataSet selectRecord(SessionPool sessionPool,String sql) {
        log.info("iotdb数据查询：sql:[{}]",sql);
        SessionDataSetWrapper sessionDataSetWrapper = null;
        try {
            log.info("iotdb SQL查询：sql:[{}]", sql);
            sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
            return sessionDataSetWrapper.getSessionDataSet();
        } catch (Exception e) {
            log.error("IotDBSession executeQueryStatement失败:sql:[{}],error={}", sql, e.getMessage());
            throw new RuntimeException(e);
        }
    }


    public JSONObject getJsonFindByTime(SessionPool sessionPool,String fieldName,String deviceId,Long timestamp) {
        String sql = String.format("SELECT %s FROM %s WHERE time = %d", fieldName, deviceId, timestamp);
        SessionDataSet sessionDataSet = selectRecord(sessionPool, sql);
        try {
            while (sessionDataSet.hasNext()){
                RowRecord next = sessionDataSet.next();
                for (Field field : next.getFields()) {
                    String stringValue = field.getStringValue();
                }
            }
        } catch (StatementExecutionException e) {
            throw new RuntimeException(e);
        } catch (IoTDBConnectionException e) {
            throw new RuntimeException(e);
        }
        return null;
    }



    public static void main(String[] args) {
        SessionPool sessionPool = new SessionPool("127.0.0.1", 6667, "root", "root", 10);


        String jsonValue = """
                {
                  "name": "张三",
                  "age": 28,
                  "email": "zhangsan@example.com",
                  "isStudent": false,
                  "hobbies": ["阅读", "旅行", "编程"],
                  "address": {
                    "street": "长安街100号",
                    "city": "北京",
                    "postalCode": "100000"
                  }
                }
                """;
        JSONObject value = JSONObject.parseObject(jsonValue);

        IotDBSessionConfig iotDBSessionConfig = new IotDBSessionConfig();

        List<String> measurements = List.of("datasource");
        List<TSDataType> datatypeList = List.of(TSDataType.TEXT);
        iotDBSessionConfig.insertRecord(sessionPool,ROOT_DATA_DATAJSON,System.currentTimeMillis(),measurements,datatypeList,value);

        SessionDataSet sessionDataSet = iotDBSessionConfig.selectRecord(sessionPool,SELECT_ROOT_DATA_DATAJSON_DATASOURCE);

        HashMap<Long, Map<String, String>> LongMapHashMap = new HashMap<>();

        try {
            while (sessionDataSet.hasNext()){
                RowRecord next = sessionDataSet.next();
                Long timestamp = next.getTimestamp();
                Map<String, String> fieldMap = new HashMap<>();
                for (Field field : next.getFields()) {
                    TSDataType dataType = field.getDataType();
                    String stringValue = field.getStringValue();
                    fieldMap.put(dataType.name(), stringValue);
                }
                LongMapHashMap.put(timestamp, fieldMap);
            }
        } catch (StatementExecutionException e) {
            throw new RuntimeException(e);
        } catch (IoTDBConnectionException e) {
            throw new RuntimeException(e);
        }
        log.info("数据为：{}", JSONObject.toJSONString(LongMapHashMap));
    }

}


