package cn.reghao.tnb.content.app.config.mybatis;

import org.apache.ibatis.session.SqlSessionFactory;
//import org.apache.shardingsphere.shardingjdbc.jdbc.core.datasource.ShardingDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author reghao
 * @date 2023-12-31 01:04:32
 */
@Configuration
@MapperScan(basePackages = {
        "cn.reghao.tnb.content.app.vod.db.mapper",
        "cn.reghao.tnb.content.app.data.db.mapper",
        "cn.reghao.tnb.content.app.chat.db.mapper",
        "cn.reghao.tnb.content.app.exam.db.mapper",
        "cn.reghao.tnb.content.app.mall.db.mapper",
        "cn.reghao.tnb.content.app.geo.db.mapper"
},
        sqlSessionFactoryRef = "sqlSessionFactory")
public class SqlSessionConfig {
    //@Bean(name = "sqlSessionTemplate")
    /*public SqlSessionTemplate sqlSessionTemplate(@Qualifier("shardingDataSource") DataSource dataSource) throws Exception {
        if (dataSource instanceof ShardingDataSource) {
            ShardingDataSource shardingDataSource = (ShardingDataSource) dataSource;
            Map<String, DataSource> map = shardingDataSource.getDataSourceMap();
            DataSource dataSourceMaster = map.get("master");
            DataSource dataSourceSlave = map.get("slave");

            SqlSessionFactory master = getSqlSessionFactory("master", dataSourceMaster);
            SqlSessionFactory slave = getSqlSessionFactory("slave", dataSourceSlave);
            Map<Object, SqlSessionFactory> factoryMap = new HashMap<>();
            factoryMap.put("master", master);
            factoryMap.put("slave", slave);

            CustomSqlSessionTemplate sqlSessionTemplate = new CustomSqlSessionTemplate(master);
            sqlSessionTemplate.setTargetSqlSessionFactories(factoryMap);
            return sqlSessionTemplate;
        }

        throw new Exception("DataSource is not ShardingDataSource");
    }*/

    private SqlSessionFactory getSqlSessionFactory(String databaseId, DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        factoryBean.setPlugins(pageListInterceptor());

        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setDefaultFetchSize(100);
        configuration.setDefaultStatementTimeout(30);
        configuration.setDatabaseId(databaseId);
        factoryBean.setConfiguration(configuration);

        String location = "classpath*:mapper/**/**.xml";
        factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(location));
        return factoryBean.getObject();
    }

    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(/*@Qualifier("dynamicDataSource")*/ DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        factoryBean.setPlugins(pageListInterceptor());

        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setDefaultFetchSize(100);
        configuration.setDefaultStatementTimeout(30);
        factoryBean.setConfiguration(configuration);

        String location = "classpath*:mapper/**/**.xml";
        factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(location));
        return factoryBean.getObject();
    }

    private PageListInterceptor pageListInterceptor() {
        return new PageListInterceptor();
    }

    @Bean(value = "transactionManager")
    public PlatformTransactionManager annotationDrivenTransactionManager(/*@Qualifier("dynamicDataSource") */DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}
