package com.gyee.wisdom.dataadapter.runner;

import com.gyee.wisdom.common.data.timeseries.GeneralTsData;
import com.gyee.wisdom.common.data.timeseries.TsDataType;
import com.gyee.wisdom.common.data.timeseries.TsPoint;
import com.gyee.wisdom.common.data.timeseries.TsPointData;
import com.gyee.wisdom.common.data.windturbine.Windturbine;
import com.gyee.wisdom.dao.things.IThingsPointDao;
import com.gyee.wisdom.dao.timeseries.ILatestDao;
import com.gyee.wisdom.dataadapter.domain.thing.WindturbineService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;
import java.util.stream.Collectors;

//@Component
@Slf4j
public class SpringStartAfter implements ApplicationRunner {

    @Value("${taoscz.server_ip:192.168.1.60}")
    private String serverIp;

    @Value("${taoscz.server_port:6030}")
    private int serverPort;

    @Value("${taoscz.db_name:power_test}")
    private String dbName;

    @Value("${taoscz.user_name:root}")
    private String userName;

    @Value("${taoscz.password:taosdata}")
    private String password;

    @Autowired
    private ILatestDao latestDao;

    @Autowired
    private WindturbineService windturbineService;
    @Autowired
    private IThingsPointDao thingsPointDao;


    List<TsPoint> allTsPoint = null;

    @Override
    public void run(ApplicationArguments args) throws Exception {

        //牛首山风电场 taos库创建，taos库保存数据为90天
        //initDatabase("FS_FDC", 90);
//        //牛首山风电场 ai测点表创建，超级表名为windturbineai，风机型号为UP82
        //initTableAI("FS_FDC", "pointai", "UP82-1500");
//        //牛首山风电场 di测点表创建，超级表名为windturbinedi，风机型号为UP82
        //initTableDI("FS_FDC", "pointdi", "UP82-1500");

//        Random r = new Random();
//        Long ts = new Date().getTime();
//        final List<TsPoint> allTsPoint = thingsPointDao.getAllTsPoint().stream().filter(s -> !s.getThingId().equals("BY_FDC")).collect(Collectors.toList());
//        List<TsPointData> dataList = new ArrayList<>();
//        for (TsPoint point :
//                allTsPoint) {
//            TsPointData tsPointData = new TsPointData();
//            tsPointData.setTagName(point.getId());
//            GeneralTsData generalTsData = new GeneralTsData();
//            Double speed = r.nextDouble() * 6 + 3;
//            generalTsData.setDoubleValue(java.util.Optional.of(speed));
//            ts = ts + 1000;
//            generalTsData.setTs(ts);
//            tsPointData.setTsData(generalTsData);
//            dataList.add(tsPointData);
//        }
//
//        while (true) {
//            Thread.sleep(999);
//            writeThread(dataList).run();
//
//        }


    }

    //模拟taos数据写入
    private Thread writeThread(List<TsPointData> list) {
        Thread t = new Thread() {

            @SneakyThrows
            @Override
            public void run() {
                Random r = new Random();
                Long ts = new Date().getTime();
                for (TsPointData tsPointData :
                        list) {


                    GeneralTsData generalTsData = new GeneralTsData();

                    if (tsPointData.getTagName().contains("_DI00")) {
                        boolean speed = new Random().nextBoolean();
                        generalTsData.setDoubleValue(java.util.Optional.of(speed ? 1.0 : 0.0));

                        generalTsData.setTs(ts);
                        tsPointData.setTsData(generalTsData);
                    } else {
                        Double speed = r.nextDouble() * 6 + 3;
                        generalTsData.setDoubleValue(java.util.Optional.of(speed));

                        generalTsData.setTs(ts);
                        tsPointData.setTsData(generalTsData);
                    }


                }
                boolean b = latestDao.writeLatest(list);
            }
        };
        return t;

    }

    /**
     * @param
     * @param stationName 风场id
     * @param keepDay     数据存储天数
     * @return
     * @author Wanghs
     * @description
     * @date 2023/2/22
     **/

    private void initDatabase(String stationName, int keepDay) throws ClassNotFoundException {


        log.error("开始执行创建taos库");
        try {
//            final List<Windturbine> windturbines = windturbineService.queryWindturbine(stationName, "MY-1500");
//
//            log.error("查询风机完毕" + windturbines.size());
            // Class.forName("com.taosdata.jdbc.TSDBDriver");
            // String jdbcUrl = "jdbc:TAOS://" + serverIp + ":" + serverPort + "/" + dbName + "?user=" + userName + "&password=" + password;

            Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
            String jdbcUrl = "jdbc:TAOS-RS://" + serverIp + ":" + serverPort + "/" + dbName + "?user=" + userName + "&password=" + password;

            Properties connProps = new Properties();
            connProps.setProperty("charset", "UTF-8");
            connProps.setProperty("locale", "en_US.UTF-8");
            connProps.setProperty("timezone", "UTC-8");
            final Connection connection = DriverManager.getConnection(jdbcUrl, connProps);


            //String createDatabaseSql="create database if not exists "+stationName;
            final Statement statement = connection.createStatement();
            //statement.executeUpdate(createDatabaseSql);

            String createSTableSql = "create database " + dbName + " replica 1 quorum 1 days 1 keep " + keepDay + " cache 16 blocks 6" +
                    " minrows 100 maxrows 4096 wal 1 fsync 3000 comp 2 cachelast 0 precision 'ms' update 1";
            statement.executeUpdate(createSTableSql);


        } catch (SQLException ex) {
            log.error(ex.getMessage());
            log.error("=============");
            ex.printStackTrace();
            log.error(ex.getStackTrace().toString());
        }


    }


    private void initTableAI(String stationId, String stableName, String modelId) throws ClassNotFoundException {
        log.error("开始执行创建taos库");
        try {
            //final List<Windturbine> windturbines = windturbineService.queryWindturbine(stationId, modelId);

            //log.error("查询风机完毕" + windturbines.size());
            // Class.forName("com.taosdata.jdbc.TSDBDriver");
            // String jdbcUrl = "jdbc:TAOS://" + serverIp + ":" + serverPort + "/" + dbName + "?user=" + userName + "&password=" + password;

            Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
            String jdbcUrl = "jdbc:TAOS-RS://" + serverIp + ":" + serverPort + "/" + dbName + "?user=" + userName + "&password=" + password;

            Properties connProps = new Properties();
            connProps.setProperty("charset", "UTF-8");
            connProps.setProperty("locale", "en_US.UTF-8");
            connProps.setProperty("timezone", "UTC-8");
            final Connection connection = DriverManager.getConnection(jdbcUrl, connProps);


            //String createDatabaseSql="create database if not exists "+stationName;
            final Statement statement = connection.createStatement();
            //statement.executeUpdate(createDatabaseSql);

            String createSTableSql = "create stable if not exists " + dbName + "." + stableName + "(ts timestamp,value double) " +
                    "tags(point binary(50),description nchar(100),station binary(20),turbine binary(20));";
            statement.executeUpdate(createSTableSql);
            if (allTsPoint == null)
                allTsPoint = thingsPointDao.getAllTsPoint();

            List<TsPoint> doublePointList = allTsPoint.stream().filter(s -> s.getTsDataType() == TsDataType.DOUBLE).collect(Collectors.toList());
            Date st = new Date();
/*            for (Windturbine data :
                    windturbines) {

                 List<TsPoint> collect = doublePointList.stream().filter(s -> s.getThingId().equals(data.getId())).collect(Collectors.toList());

                for (TsPoint point :
                        collect) {
                    String createTableSql = "create table if not exists " + stationId + "." + point.getId() + " using " + stationId + "." + stableName + " tags(\"" + point.getId() + "\"" + ");";

                    statement.executeUpdate(createTableSql);
                }
            }*/
            for (TsPoint point : doublePointList) {
                String createTableSql = "create table if not exists " + dbName + "." + point.getId() + " using " + dbName + "." + stableName +
                        " tags('" + point.getId() +"','','',''" + ");";

                statement.executeUpdate(createTableSql);
            }
            Date et = new Date();
            log.error("数据库创建完毕，耗时" + (et.getTime() - st.getTime()));
        } catch (SQLException ex) {
            log.error(ex.getMessage());
            log.error("=============");
            ex.printStackTrace();
            log.error(ex.getStackTrace().toString());
        }


    }

    private void initTableDI(String stationId, String stableName, String modelId) throws ClassNotFoundException {
        log.error("开始执行创建taos库");
        try {
            //final List<Windturbine> windturbines = windturbineService.queryWindturbine(stationId, modelId);

            //log.error("查询风机完毕" + windturbines.size());
            // Class.forName("com.taosdata.jdbc.TSDBDriver");
            // String jdbcUrl = "jdbc:TAOS://" + serverIp + ":" + serverPort + "/" + dbName + "?user=" + userName + "&password=" + password;

            Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
            String jdbcUrl = "jdbc:TAOS-RS://" + serverIp + ":" + serverPort + "/" + dbName + "?user=" + userName + "&password=" + password;

            Properties connProps = new Properties();
            connProps.setProperty("charset", "UTF-8");
            connProps.setProperty("locale", "en_US.UTF-8");
            connProps.setProperty("timezone", "UTC-8");
            final Connection connection = DriverManager.getConnection(jdbcUrl, connProps);


            //String createDatabaseSql="create database if not exists "+stationName;
            final Statement statement = connection.createStatement();
            //statement.executeUpdate(createDatabaseSql);

            String createSTableSql = "create stable if not exists " + dbName + "." + stableName + "(ts timestamp,value bool)" +
                    "tags(point binary(50),description nchar(100),station binary(20),turbine binary(20));";
            statement.executeUpdate(createSTableSql);


            if (allTsPoint == null)
                allTsPoint = thingsPointDao.getAllTsPoint();

            List<TsPoint> booleanPointList = allTsPoint.stream().filter(s -> s.getTsDataType() == TsDataType.BOOLEAN).collect(Collectors.toList());
            Date st = new Date();
            /*for (Windturbine data :
                    windturbines) {

                 List<TsPoint> collect = booleanPointList.stream().filter(s -> s.getThingId().equals(data.getId())).collect(Collectors.toList());

                for (TsPoint point :
                        collect) {
                    String createTableSql = "create table if not exists " + stationId + "." + point.getId() + " using " + stationId + "." + stableName + " tags(\"" + point.getId() + "\"" + ");";


                    statement.executeUpdate(createTableSql);
                }
            }*/
            for (TsPoint point :
                    booleanPointList) {
                String createTableSql = "create table if not exists " + dbName + "." + point.getId() + " using " + dbName + "." + stableName +
                        " tags('" + point.getId() +"','','',''" + ");";


                statement.executeUpdate(createTableSql);
            }
            Date et = new Date();
            log.error("数据库创建完毕，耗时" + (et.getTime() - st.getTime()));
        } catch (SQLException ex) {
            log.error(ex.getMessage());
            log.error("=============");
            ex.printStackTrace();
            log.error(ex.getStackTrace().toString());
        }


    }

}
