package com.rehome.mqttclienttemperature.controller;


import com.google.gson.Gson;
import com.rehome.mqttclienttemperature.datasource.DataSource;
import com.rehome.mqttclienttemperature.dto.ResponseDto;
import com.rehome.mqttclienttemperature.dto.ResponseTemperatureDto;
import com.rehome.mqttclienttemperature.dto.TemperatureDto;
import com.rehome.mqttclienttemperature.entity.Temperature;
import com.rehome.mqttclienttemperature.service.TemperatureService;
import com.rehome.mqttclienttemperature.utils.JdbcUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * 背景
 * 现在的数据层的开发，大多会使用如MyBatis或JPA之类的开发工具。这些开发工具给我们的开发过程中带来了极大的便利。
 * 但是在一些极端的场景下往往原生的jdbc方式操作数据库更灵活，性能更高。由于部分场景下MyBatis或JPA之类无法满足我的需求，所以我打算自己封装一套查数据库的工具类。
 * <p>
 * 我们会用到fastjson,druid,mysql所以pom.xml增加依赖如下：
 *
 * <dependency>
 * <groupId>com.alibaba</groupId>
 * <artifactId>fastjson</artifactId>
 * <version>1.2.62</version>
 * </dependency>
 * <dependency>
 * <groupId>com.alibaba</groupId>
 * <artifactId>druid</artifactId>
 * <version>1.1.9</version>
 * </dependency>
 * <!-- Mysql驱动包 -->
 * <dependency>
 * <groupId>mysql</groupId>
 * <artifactId>mysql-connector-java</artifactId>
 * </dependency>
 */

/**
 * 源码下载
 * https://download.csdn.net/download/lxyoucan/85094574
 * <p>
 * 参考
 * https://github.com/freakchick/DBApi
 * <p>
 * SpringBoot中封装jdbc工具类
 * https://blog.csdn.net/lxyoucan/article/details/124042295
 */

@Slf4j
@RestController
public class JdbcDemoController {

    @Resource
    private TemperatureService temperatureService;


    public static DataSource ds = new DataSource();

    static {
        //配置数据源
        ds.setId("1");
        ds.setName("mysql");
        ds.setUrl("jdbc:mysql://192.168.1.24:3306/appserver?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true");
        ds.setUsername("root");
        ds.setPassword("Skyinno251,");
        ds.setDriver("com.mysql.cj.jdbc.Driver");

//        ds.setId("2");
//        ds.setName("oracle");
//        ds.setUrl("jdbc:oracle:thin:@192.168.1.9:1521/orcl");
//        ds.setUrl("jdbc:oracle:thin:@192.168.3.7:1521/orcl");
//        ds.setUsername("appserver");
//        ds.setPassword("appserver");
//        ds.setDriver("oracle.jdbc.driver.OracleDriver");
    }

    /**
     * 查询测试
     *
     * @return
     */
    //@RequestMapping("/api/list")
    public ResponseDto queryList() {
        // 自定义一个线程池,内部包含8个线程
        ExecutorService customPool = Executors.newFixedThreadPool(8);
        // 自定义一个线程池,内部包含10个线程
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            String sql = "select * from temperature where id = ?";
            List<Object> jdbcParamValues = new ArrayList<>();
            for (int i = 2292104; i < 2298700; i++) {
                jdbcParamValues.add(i + 1);
                Gson gson = new Gson();
                ResponseDto responseDto = JdbcUtil.executeSql(ds, sql, jdbcParamValues);
                String dbQueryResult = gson.toJson(responseDto);
                log.info(dbQueryResult);
                jdbcParamValues.clear();

                ResponseTemperatureDto responseTemperatureDto = gson.fromJson(dbQueryResult, ResponseTemperatureDto.class);
                if (responseTemperatureDto.isSuccess() && responseTemperatureDto.getData() != null && responseTemperatureDto.getData().size() > 0) {
                    log.info(gson.toJson(responseTemperatureDto.getData().get(0)));
                    TemperatureDto dto = responseTemperatureDto.getData().get(0);
                    Temperature temperature = new Temperature();
                    temperature.setCreateDate(dto.getCreateDate());
                    temperature.setDataDate(dto.getDataDate());
                    temperature.setDataHour(dto.getDataHour());
                    temperature.setDataMinute(dto.getDataMinute());
                    temperature.setTopic(dto.getTopic());
                    temperature.setHumidity(String.valueOf(dto.getHumidity()));
                    temperature.setTemperature(String.valueOf(dto.getTemperature()));
                    temperature.setLocationDesc(dto.getLocationDesc());
                    temperatureService.saveTemperature(temperature);
                }
            }
            return "数据库同步成功";
        }, customPool);

        future.thenApply(result -> {
            System.out.println("Result: " + result);
            return result;
        });

        return ResponseDto.successWithMsg("数据库正在同步...");
    }

    public void completableFutureExample() {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            // 模拟耗时操作
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt(); // 重置中断状态
            }
            return 123;
        });
        // 非阻塞等待结果，但不返回结果，如果要处理结果，可以使用thenApply等
        future.thenAccept(result -> System.out.println("Result: " + result)).join();
    }

    /**
     * 查询测试
     *
     * @return
     */
    @RequestMapping("/api/getResult")
    public String getResult() {
        // 自定义一个线程池,内部包含4个线程
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            // 模拟耗时操作
            try {
                Thread.sleep(1000);
                System.out.println("异步处理完成");
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt(); // 重置中断状态
            }
            return "数据库同步成功";
        }, executorService);
        //注意，如果需要异步返回结果，再做后续操作，需要加入join()方法等待异步计算结果后回调,不然异步没有处理完直接主线程结束
        future.thenApply(result -> {
            System.out.println("Result: " + result);
            return result;
        }).join();
        System.out.println("数据库正在同步...");
        return "数据库正在同步...";
    }

    /**
     * 查询测试
     *
     * @return
     */
    @RequestMapping("/api/getResult0")
    public String getResult0() {
        // 自定义一个线程池,内部包含4个线程
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        String result = CompletableFuture.supplyAsync(() -> {
            System.out.println("Step 1: Generate number");
            return 42;
        }, executorService).thenApply(num -> {
            System.out.println("Step 2: Convert number to string");
            return "Number is: " + num;
        }).exceptionally(exception -> {
            System.out.println(exception.getMessage());
            return null;
        }).join();

        if (result==null||"".equals(result.trim())) {
            return "数据库同步异常...";
        }
        System.out.println("数据库正在同步...");
        System.out.println(result);
        return result;
    }
}

