package com.jeequan.jeepay.db.config.dynamic;

import cn.hutool.core.util.ObjUtil;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
*
* DB spring bean 配置信息
* @author terrfly
* @date 2022/3/8 9:39
*/
@Configuration
public class DataSourceSpringConfig {

    /** 获取 主 从的配置信息 **/
    @ConfigurationProperties(prefix = "db-config.master")
    @Bean(name = "masterDBProp")
    public DBProp masterDBProp() { return new DBProp(); }

    @ConfigurationProperties(prefix = "db-config.slave")
    @Bean(name = "slaveDBProp")
    public DBProp slaveDBProp() { return new DBProp(); }

    @Autowired
    @Qualifier("masterDBProp")
    private DBProp masterDBProp;

    @Autowired
    @Qualifier("slaveDBProp")
    private DBProp slaveDBProp;

    @Bean(name = "dataSource")
    public DynamicDataSource dynamicDataSource() throws SQLException {

        DynamicDataSource result = new DynamicDataSource();

        // 全部db连接池
        Map<Object, Object> dbMap = new HashMap<>();
        dbMap.put(DynamicDataSource.MASTER, fillDS(masterDBProp));
        dbMap.put(DynamicDataSource.SLAVE, fillDS(slaveDBProp));

        // 默认master
        result.setDefaultTargetDataSource(dbMap.get(DynamicDataSource.MASTER));

        result.setTargetDataSources(dbMap);
        return result;
    }

    /** 填充 datasoruce */
    private DruidDataSource fillDS(DBProp thisProp) throws SQLException {
        DruidDataSource result = new DruidDataSource();

        result.setDbType(ObjUtil.defaultIfNull(thisProp.getDbType(), masterDBProp.getDbType()));
        result.setDriverClassName(ObjUtil.defaultIfNull(thisProp.getDriverClassName(), masterDBProp.getDriverClassName()));
        result.setUrl(ObjUtil.defaultIfNull(thisProp.getUrl(), masterDBProp.getUrl()));
        result.setUsername(ObjUtil.defaultIfNull(thisProp.getUsername(), masterDBProp.getUsername()));
        result.setPassword(ObjUtil.defaultIfNull(thisProp.getPassword(), masterDBProp.getPassword()));
        result.setInitialSize(ObjUtil.defaultIfNull(thisProp.getInitialSize(), masterDBProp.getInitialSize()));
        result.setMinIdle(ObjUtil.defaultIfNull(thisProp.getMinIdle(), masterDBProp.getMinIdle()));
        result.setMaxActive(ObjUtil.defaultIfNull(thisProp.getMaxActive(), masterDBProp.getMaxActive()));
        result.setMaxWait(ObjUtil.defaultIfNull(thisProp.getMaxWait(), masterDBProp.getMaxWait()));
        result.setTestWhileIdle(ObjUtil.defaultIfNull(thisProp.getTestWhileIdle(), masterDBProp.getTestWhileIdle()));
        result.setTestOnBorrow(ObjUtil.defaultIfNull(thisProp.getTestOnBorrow(), masterDBProp.getTestOnBorrow()));
        result.setTestOnReturn(ObjUtil.defaultIfNull(thisProp.getTestOnReturn(), masterDBProp.getTestOnReturn()));
        result.setTimeBetweenEvictionRunsMillis(ObjUtil.defaultIfNull(thisProp.getTimeBetweenEvictionRunsMillis(), masterDBProp.getTimeBetweenEvictionRunsMillis()));
        result.setMinEvictableIdleTimeMillis(ObjUtil.defaultIfNull(thisProp.getMinEvictableIdleTimeMillis(), masterDBProp.getMinEvictableIdleTimeMillis()));
        result.setValidationQuery(ObjUtil.defaultIfNull(thisProp.getValidationQuery(), masterDBProp.getValidationQuery()));
        result.setPoolPreparedStatements(ObjUtil.defaultIfNull(thisProp.getPoolPreparedStatements(), masterDBProp.getPoolPreparedStatements()));
        result.setMaxPoolPreparedStatementPerConnectionSize(ObjUtil.defaultIfNull(thisProp.getMaxPoolPreparedStatementPerConnectionSize(), masterDBProp.getMaxPoolPreparedStatementPerConnectionSize()));
        result.setFilters(ObjUtil.defaultIfNull(thisProp.getFilters(), masterDBProp.getFilters()));
        result.setConnectionProperties(ObjUtil.defaultIfNull(thisProp.getConnectionProperties(), masterDBProp.getConnectionProperties()));

        return result;
    }
}
