package cn.gintone.iotdbUtils;

import cn.gintone.config.IotDbConfig;
import cn.gintone.dto.FileDecLogInfo;
import cn.gintone.dto.SpePeoLogInfo;
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.tsfile.enums.TSDataType;
import org.apache.tsfile.file.metadata.enums.CompressionType;
import org.apache.tsfile.file.metadata.enums.TSEncoding;
import org.apache.tsfile.read.common.Field;
import org.apache.tsfile.read.common.RowRecord;

import java.util.ArrayList;
import java.util.List;

/**
 * 重点、特殊人群解密日志揭露
 */
public class SpecialPeopleIotDbUtils {

    public static void createSpeLogInfoTimeseries(IotDbConfig iotDbConfig) {
        try {
            List<String> nodeUrls = new ArrayList<>();
            nodeUrls.add(iotDbConfig.getIp() + ":" + iotDbConfig.getPort());
            SessionPool sessionPool =
                    new SessionPool.Builder()
                            .nodeUrls(nodeUrls)
                            .user(iotDbConfig.getUsername())
                            .password(iotDbConfig.getPassword())
                            .maxSize(3)
                            .build();


            // 设置数据类型，设置默认编码模式，设置默认压缩模式
            sessionPool.createTimeseries("root.myDecFileLogInfo.speLog.userId", TSDataType.TEXT, TSEncoding.PLAIN, CompressionType.UNCOMPRESSED);
            sessionPool.createTimeseries("root.myDecFileLogInfo.speLog.username", TSDataType.TEXT, TSEncoding.PLAIN, CompressionType.UNCOMPRESSED);
            sessionPool.createTimeseries("root.myDecFileLogInfo.speLog.sysAbbre", TSDataType.TEXT, TSEncoding.PLAIN, CompressionType.UNCOMPRESSED);
            sessionPool.createTimeseries("root.myDecFileLogInfo.speLog.content", TSDataType.TEXT, TSEncoding.PLAIN, CompressionType.UNCOMPRESSED);
            sessionPool.createTimeseries("root.myDecFileLogInfo.speLog.privateKey", TSDataType.TEXT, TSEncoding.PLAIN, CompressionType.UNCOMPRESSED);
            sessionPool.createTimeseries("root.myDecFileLogInfo.speLog.clientIp", TSDataType.TEXT, TSEncoding.PLAIN, CompressionType.UNCOMPRESSED);
            sessionPool.close();
        } catch (IoTDBConnectionException e) {
            throw new RuntimeException(e);
        } catch (StatementExecutionException e) {
            throw new RuntimeException(e);
        }
    }

    // 重点人群解密记录
    public static void inserOne(IotDbConfig iotDbConfig, SpePeoLogInfo spePeoLogInfo) {
        if (null == spePeoLogInfo) {
            return;
        }
        try {
            List<String> nodeUrls = new ArrayList<>();
            nodeUrls.add(iotDbConfig.getIp() + ":" + iotDbConfig.getPort());
            SessionPool sessionPool =
                    new SessionPool.Builder()
                            .nodeUrls(nodeUrls)
                            .user(iotDbConfig.getUsername())
                            .password(iotDbConfig.getPassword())
                            .maxSize(3)
                            .build();

            List<String> list5 = new ArrayList<>();
            list5.add("userId");
            list5.add("username");
            list5.add("sysAbbre");
            list5.add("content");
            list5.add("privateKey");
            list5.add("clientIp");

            List<TSDataType> list6 = new ArrayList<>();
            list6.add(TSDataType.TEXT);
            list6.add(TSDataType.TEXT);
            list6.add(TSDataType.TEXT);
            list6.add(TSDataType.TEXT);
            list6.add(TSDataType.TEXT);
            list6.add(TSDataType.TEXT);

            List<Object> values = new ArrayList<>();
            values.add(spePeoLogInfo.getUserId());
            values.add(spePeoLogInfo.getUsername());
            values.add(spePeoLogInfo.getSysAbbre());
            values.add(spePeoLogInfo.getContent());
            values.add(spePeoLogInfo.getPrivateKey());
            values.add(spePeoLogInfo.getClientIp());
            sessionPool.insertRecord("root.myDecFileLogInfo.speLog", System.currentTimeMillis(), list5, list6, values);
            sessionPool.close();
        } catch (IoTDBConnectionException e) {
            throw new RuntimeException(e);
        } catch (StatementExecutionException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 查询总条数
     * @param iotDbConfig
     * @param spePeoLogInfo
     * @return
     */
    public static long countSpeLogInfo(IotDbConfig iotDbConfig, SpePeoLogInfo spePeoLogInfo) {
        long num = 0;
        try {
            List<String> nodeUrls = new ArrayList<>();
            nodeUrls.add(iotDbConfig.getIp() + ":" + iotDbConfig.getPort());
            SessionPool sessionPool =
                    new SessionPool.Builder()
                            .nodeUrls(nodeUrls)
                            .user(iotDbConfig.getUsername())
                            .password(iotDbConfig.getPassword())
                            .maxSize(3)
                            .build();


            StringBuffer sb = new StringBuffer();
            sb.append("select count(userId) from root.myDecFileLogInfo.speLog");
            if ((null != spePeoLogInfo.getEndTime() && 0 != spePeoLogInfo.getEndTime())
                    || (null != spePeoLogInfo.getBeginTime() && 0 != spePeoLogInfo.getBeginTime())) {
                sb.append(" where");
                boolean needAnd = false;
                if (null != spePeoLogInfo.getEndTime() && 0 != spePeoLogInfo.getEndTime() ) {
                    needAnd = true;
                    sb.append(" time <= "+ spePeoLogInfo.getEndTime());
                }
                if (null != spePeoLogInfo.getBeginTime() && 0 != spePeoLogInfo.getBeginTime()) {
                    if (needAnd) {
                        sb.append(" and");
                    }
                    needAnd = true;
                    sb.append(" time >= "+ spePeoLogInfo.getBeginTime());

                }
            }
            String sql = sb.toString();
            System.out.println(sql);
            SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
            System.out.println(columnNames);
            while (sessionDataSetWrapper.hasNext()) {
                RowRecord next = sessionDataSetWrapper.next(); // 取出一行数据
                long timestamp = next.getTimestamp(); // 获取这行的时间戳
                List<Field> fields = next.getFields();
                Field field0 = fields.get(0);
                num = field0.getLongV();
            }

            sessionPool.close();
        } catch (IoTDBConnectionException e) {
            throw new RuntimeException(e);
        } catch (StatementExecutionException e) {
            throw new RuntimeException(e);
        }

        return num;
    }

    public static List<SpePeoLogInfo> selectSpeLogInfo(IotDbConfig iotDbConfig, SpePeoLogInfo spePeoLogInfo) {
        List<SpePeoLogInfo> spePeoLogInfoList = new ArrayList<>();
        try {
            List<String> nodeUrls = new ArrayList<>();
            nodeUrls.add(iotDbConfig.getIp() + ":" + iotDbConfig.getPort());
            SessionPool sessionPool =
                    new SessionPool.Builder()
                            .nodeUrls(nodeUrls)
                            .user(iotDbConfig.getUsername())
                            .password(iotDbConfig.getPassword())
                            .maxSize(3)
                            .build();

            int offsetNum = (spePeoLogInfo.getPageNum() - 1) * spePeoLogInfo.getPageSize();
            int limitNum = spePeoLogInfo.getPageSize();
            StringBuffer sb = new StringBuffer();
            sb.append("select userId, username, sysAbbre, content, privateKey, clientIp from root.myDecFileLogInfo.speLog");
            if ((null != spePeoLogInfo.getEndTime() && 0 != spePeoLogInfo.getEndTime())
                    || (null != spePeoLogInfo.getBeginTime() && 0 != spePeoLogInfo.getBeginTime())) {
                sb.append(" where");
                boolean needAnd = false;
                if (null != spePeoLogInfo.getEndTime() && 0 != spePeoLogInfo.getEndTime() ) {
                    needAnd = true;
                    sb.append(" time <= "+ spePeoLogInfo.getEndTime());
                }
                if (null != spePeoLogInfo.getBeginTime() && 0 != spePeoLogInfo.getBeginTime()) {
                    if (needAnd) {
                        sb.append(" and");
                    }
                    needAnd = true;
                    sb.append(" time >= "+ spePeoLogInfo.getBeginTime());

                }
            }
            sb.append(" order by time desc offset " + offsetNum + " limit " + limitNum);
            String sql = sb.toString();
            System.out.println(sql);
            SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
            System.out.println(columnNames);
            while (sessionDataSetWrapper.hasNext()) {
                RowRecord next = sessionDataSetWrapper.next(); // 取出一行数据
                long timestamp = next.getTimestamp(); // 获取这行的时间戳
                List<Field> fields = next.getFields();
                Field field0 = fields.get(0);
                String userId = field0.getStringValue();
                Field field1 = fields.get(1);
                String username = field1.getStringValue();
                Field field2 = fields.get(2);
                String sysAbbre = field2.getStringValue();
                Field field3 = fields.get(3);
                String content = field3.getStringValue();
                Field field4 = fields.get(4);
                String privateKey = field4.getStringValue();
                Field field5 = fields.get(5);
                String clientIp = field5.getStringValue();

                SpePeoLogInfo splInfo = new SpePeoLogInfo();
                splInfo.setTimesta(timestamp);
                splInfo.setTimestaStr(MyDateUtils.longToString(timestamp));
                splInfo.setUserId(userId);
                splInfo.setUsername(username);
                splInfo.setSysAbbre(sysAbbre);
                splInfo.setContent(content);
//                splInfo.setPrivateKey(privateKey);
                splInfo.setClientIp(clientIp);
                spePeoLogInfoList.add(splInfo);
            }

            sessionPool.close();
        } catch (IoTDBConnectionException e) {
            throw new RuntimeException(e);
        } catch (StatementExecutionException e) {
            throw new RuntimeException(e);
        }

        return spePeoLogInfoList;
    }
}
