/*
 * Copyright (c) 2018-2028, AoKunSang All rights reserved.
 * 我问青山何时老，青山问我几时闲，
 * 不是闲人闲不得，能闲必非等闲人。
 */
package org.springblade.datasource.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.dynamic.datasource.creator.druid.DruidConfig;
import lombok.extern.slf4j.Slf4j;
import org.springblade.datasource.enums.DsTypeEnum;
import org.springblade.datasource.model.DatasourceDto;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;
import java.util.Properties;

/**
 * 数据源操作类
 *
 * @author wookvn
 * @datetime 2025-01-13 17:26:30
 */
@Slf4j
public class DatasourceUtil {

    /**
     * 测试数据源
     *
     * @param ds
     * @return
     */
    public static String testDs(DatasourceDto ds) {
        try (Connection connection = DatasourceUtil.createConnection(ds);
             Statement statement = connection.createStatement();){
            statement.executeQuery(ds.getDsTypeSyl().getValidationQuery());
            return null;
        } catch (Exception e) {
            log.error("测试数据源连接失败：" + e.getMessage(), e);
            return e.getMessage();
        }
    }

    /**
     * 创建连接
     * @param ds
     * @return
     * @throws SQLException
     */
    public static Connection createConnection(DatasourceDto ds) throws Exception {
        Properties props = new Properties();
        props.put("user", ds.getDsUser());
        props.put("password", ds.getDsPassword());
        //用于显示字段注释
        props.put("remarks", "true");
//		props.put("useInformationSchema", "true");
        props.put("remarksReporting", "true");
        props.put("nullCatalogMeansCurrent", "true");
        //获取每个数据库的超时时间
        Map<String, String> timeoutMap = ds.getDsTypeSyl().jdbcConnectionPropTimeout();
        if(timeoutMap == null) {
            throw new RuntimeException(String.format("数据库[%s]未设置超时时间，请先设置", ds.getDsTypeSyl().name()));
        }
        props.putAll(timeoutMap);
        if(ds.getDsTypeSyl() == DsTypeEnum.xugu) {
            Class.forName("com.xugu.cloudjdbc.Driver");
        }
        return DriverManager.getConnection(ds.getUrl(), props);
    }

    /**
     * 初始化jdbc连接配置
     * @param druidConfig
     * @param reportDs
     * @return
     */
    public static DruidConfig customConnectionConfig(DruidConfig druidConfig, DatasourceDto reportDs) {
        //先获取yml中通用的数据源配置
        DruidConfig cloneDruidConfig = BeanUtil.copyProperties(druidConfig, DruidConfig.class);
        Properties connectionProperties = new Properties();
        //先获取数据源默认jdbc连接配置
        Map<String, String> jdbcConnectionPropDefault = reportDs.getDsTypeSyl().jdbcConnectionPropDefault();
        if(jdbcConnectionPropDefault != null) {
            connectionProperties.putAll(jdbcConnectionPropDefault);
        }
        //设置自定义jdbc连接配置
        if(StrUtil.isNotBlank(reportDs.getCustomConnectProperties())) {
            JSONObject jsonObject = JSON.parseObject(reportDs.getCustomConnectProperties());
            if(jsonObject != null) {
                connectionProperties.putAll(jsonObject);
            }
        }
        //设置jdbc驱动连接属性
        cloneDruidConfig.setConnectionProperties(connectionProperties);
        //设置数据源的校验查询语句
        cloneDruidConfig.setValidationQuery(reportDs.getDsTypeSyl().getValidationQuery());
        return cloneDruidConfig;
    }
}
