package com.tax.file.config;


import com.alibaba.druid.pool.DruidDataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.*;
import org.springframework.core.env.Environment;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;
import java.sql.SQLException;

/**
 * 
 * @author Administrator
 *
 */
@Configuration
@MapperScan(basePackages = "com.tax.file.mapper", sqlSessionTemplateRef  = "acceptSqlSessionTemplate")
@ConfigurationProperties(prefix = "druid.config")
@PropertySource("classpath:druid.properties")
public class AcptDSConfig {
    private static final Logger logger = LoggerFactory.getLogger(AcptDSConfig.class);

    @Autowired
    private Environment env;
    

    @Bean(name = "acceptDataSource", destroyMethod = "close")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DruidDataSource readDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        try {
            dataSource.setFilters("config");
            dataSource.setInitialSize(Integer.parseInt(env.getProperty("druid.config.initialSize")));
            dataSource.setMinIdle(Integer.parseInt(env.getProperty("druid.config.minIdle")));
            dataSource.setMaxActive(Integer.parseInt(env.getProperty("druid.config.maxActive")));
            dataSource.setMaxWait(Long.parseLong(env.getProperty("druid.config.maxWait")));

            dataSource.setTimeBetweenEvictionRunsMillis(Long.parseLong(env.getProperty("druid.config.timeBetweenEvictionRunsMillis")));
            dataSource.setMinEvictableIdleTimeMillis(Long.parseLong(env.getProperty("druid.config.minEvictableIdleTimeMillis")));

            dataSource.setTestWhileIdle(Boolean.parseBoolean(env.getProperty("druid.config.testWhileIdle")));
            dataSource.setTestOnBorrow(Boolean.parseBoolean(env.getProperty("druid.config.testOnBorrow")));
            dataSource.setTestOnReturn(Boolean.parseBoolean(env.getProperty("druid.config.testOnReturn")));

            dataSource.setPoolPreparedStatements(Boolean.parseBoolean(env.getProperty("druid.config.poolPreparedStatements")));
            dataSource.setMaxOpenPreparedStatements(Integer.parseInt(env.getProperty("druid.config.maxOpenPreparedStatements")));
        } catch (SQLException e) {
            logger.error("readDataSource error, env={}", env, e);
        }

        return dataSource;
    }

    @Bean(name = "acceptSqlSessionFactory")
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("acceptDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:com/tax/file/mapper/*.xml"));
        return bean.getObject();
    }

    @Bean(name = "acceptTransactionManager")
    public DataSourceTransactionManager testTransactionManager(@Qualifier("acceptDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Primary
    @Lazy(false)
    @Bean(name = "acceptSqlSessionTemplate")
    public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("acceptSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory,ExecutorType.SIMPLE);
    }

    @Lazy(false)
    @Bean(name = "batchSqlSessionTemplate")
    public SqlSessionTemplate batchSqlSessionTemplate(@Qualifier("acceptSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory,ExecutorType.BATCH);
    }

}
