package com.hzya.frame.serviceUtil;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.exception.CannotFindDataSourceException;
import com.hzya.frame.datasource.DataSourceUtilProperties;
import com.hzya.frame.sysnew.application.database.entity.SysApplicationDatabaseEntity;
import com.hzya.frame.sysnew.application.entity.SysApplicationDatasourceDto;
import com.hzya.frame.util.AESUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DriverManager;


@Component
public class DsDataSourceUtil {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Resource
    private DataSource dataSource;

    public void addDataSource(SysApplicationDatabaseEntity sysDataSourceVo) throws Exception {
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        JSONObject defaultDataSourceProperties = new JSONObject();
        defaultDataSourceProperties.put("datasource_code", sysDataSourceVo.getSourceCode());
        defaultDataSourceProperties.put("source_url", sysDataSourceVo.getSourceUrl());
        defaultDataSourceProperties.put("source_type", sysDataSourceVo.getSourceTypeName());
        defaultDataSourceProperties.put("login_name", sysDataSourceVo.getLoginName());
        defaultDataSourceProperties.put("password", AESUtil.decrypt(sysDataSourceVo.getPassword()));
        defaultDataSourceProperties.put("db_name", sysDataSourceVo.getDbName());
        logger.info("***初始化数据源-{}：*********", sysDataSourceVo.getSourceName());
        DruidDataSource dataSource = createDefaultDataSource(defaultDataSourceProperties);
        ds.addDataSource(sysDataSourceVo.getSourceCode(), dataSource);
        logger.info("***初始化数据源-{}成功：*********", sysDataSourceVo.getSourceName());
    }
    /**
     * @param code
     * @return boolean
     * @Author lvleigang
     * @Description 删除数据源
     * @Date 11:40 上午 2023/9/6
     **/
    public void removeDataSource(String code) {
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        try {
            DataSource dataSource = ds.getDataSource(code);
            ds.removeDataSource(code);
        } catch (CannotFindDataSourceException var4) {
            logger.info("***初始化数据源-{}不存在不需要删除：*********", code);
        }
    }

    /**
     * @param sysApplicationDatabaseEntity
     * @return boolean
     * @Author lvleigang
     * @Description 修改数据源
     * @Date 11:40 上午 2023/9/6
     **/
    public void editDataSource(SysApplicationDatabaseEntity sysApplicationDatabaseEntity) throws Exception {
        //先删除后添加
        removeDataSource(sysApplicationDatabaseEntity.getSourceCode());
        addDataSource(sysApplicationDatabaseEntity);
    }


    private DruidDataSource createDefaultDataSource(JSONObject defaultDataSourceProperties) throws RuntimeException {
        //根据datasource_code查询数据源配置信息
        String datasource_code = String.valueOf(defaultDataSourceProperties.get("datasource_code"));
        String source_url = String.valueOf(defaultDataSourceProperties.get("source_url"));
        String login_name = String.valueOf(defaultDataSourceProperties.get("login_name"));
        String password = String.valueOf(defaultDataSourceProperties.get("password"));
        String db_name = String.valueOf(defaultDataSourceProperties.get("db_name"));
        String source_type = String.valueOf(defaultDataSourceProperties.get("source_type"));
        if (defaultDataSourceProperties != null) {
            String driveClass = "";
            if ("mysql".equalsIgnoreCase(source_type)) {
                driveClass = DataSourceUtilProperties.MYSQLDRIVER_6;
            } else if ("oracle".equalsIgnoreCase(source_type)) {
                driveClass = DataSourceUtilProperties.ORACLEDRIVER;
            } else if ("sqlserver2000".equalsIgnoreCase(source_type)) {
                driveClass = DataSourceUtilProperties.SQL2000DRIVER;
            } else if ("sqlServer".equalsIgnoreCase(source_type)) {
                driveClass = DataSourceUtilProperties.SQL2005DRIVER;
            }
            try {
                //测试连接
                Class.forName(driveClass);
                Connection connection = DriverManager.getConnection(source_url, login_name, password);// 相当于连接数据库
                if (connection != null) {
                    //初始化数据源信息
                    DruidDataSource druidDataSource = new DruidDataSource();
                    druidDataSource.setUrl(source_url);
                    druidDataSource.setUsername(login_name);
                    druidDataSource.setPassword(password);
                    druidDataSource.setName(db_name);
                    druidDataSource.setDriverClassName(driveClass);
                    druidDataSource.setInitialSize(5);
                    druidDataSource.setMinIdle(5);
                    druidDataSource.setMaxActive(100);
                    druidDataSource.setMaxWait(60000);
                    druidDataSource.setTimeBetweenEvictionRunsMillis(60000);
                    druidDataSource.setMinEvictableIdleTimeMillis(300000);
                    druidDataSource.setMaxEvictableIdleTimeMillis(600000);
                    if ("oracle".equals(source_type)) {
                        druidDataSource.setValidationQuery("select 1 from dual");
                    } else {
                        druidDataSource.setValidationQuery("SELECT 1");
                    }
                    druidDataSource.setTestWhileIdle(true);
                    druidDataSource.setTestOnBorrow(false);
                    druidDataSource.setTestOnReturn(false);
                    druidDataSource.setPoolPreparedStatements(true);
                    druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(20);
                    druidDataSource.setRemoveAbandoned(true);
                    druidDataSource.setRemoveAbandonedTimeout(999999);
                    druidDataSource.init();
                    return druidDataSource;
                } else {
                    throw new RuntimeException("测试默认数据库连接失败datasource_code：" + datasource_code);
                }
            } catch (Exception e) {
                logger.info("==================创建数据源失败===================");
                throw new RuntimeException("创建数据源失败" + e.getMessage());
            }


        } else {
            throw new RuntimeException("source_code:" + datasource_code + "不存在");
        }
    }

    //测试连接
    public boolean testConnection(SysApplicationDatasourceDto dataSourceEntity){
        //根据datasource_code查询数据源配置信息
        String driveClass = "";//1、oracle 2、sqlServer3、mysql
        if ("3".equalsIgnoreCase(dataSourceEntity.getSourceType())) {
            driveClass = DataSourceUtilProperties.MYSQLDRIVER_6;
        } else if ("1".equalsIgnoreCase(dataSourceEntity.getSourceType())) {
            driveClass = DataSourceUtilProperties.ORACLEDRIVER;
        } else if ("sqlserver2000".equalsIgnoreCase(dataSourceEntity.getSourceType())) {
            driveClass = DataSourceUtilProperties.SQL2000DRIVER;
        } else if ("2".equalsIgnoreCase(dataSourceEntity.getSourceType())) {
            driveClass = DataSourceUtilProperties.SQL2005DRIVER;
        }else if ("4".equalsIgnoreCase(dataSourceEntity.getSourceType())) {
            driveClass = DataSourceUtilProperties.dm;
        }
        try {
            //测试连接
            Class.forName(driveClass);
            Connection connection = DriverManager.getConnection(dataSourceEntity.getSourceUrl(), dataSourceEntity.getLoginName(), dataSourceEntity.getPassword());// 相当于连接数据库
            if (connection != null) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            logger.error("测试数据源失败："+e.getMessage());
            return false;
        }
    }
}
