package com.leanwo.activiti.config;

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

import javax.sql.DataSource;

import org.activiti.engine.impl.cfg.multitenant.TenantAwareDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.alibaba.druid.pool.DruidDataSource;

@Configuration
@RefreshScope
public class DataSourceConfiguration {

	private static Logger logger = LoggerFactory.getLogger(DataSourceConfiguration.class);

	@Value("${template.dataSource0.url}")
	private String dbUrl;
	@Value("${template.dataSource0.username}")
	private String username;
	@Value("${template.dataSource0.password}")
	private String password;
	@Value("${template.dataSource0.initialSize}")
	private int initialSize;
	@Value("${template.dataSource0.minIdle}")
	private int minIdle;
	@Value("${template.dataSource0.maxActive}")
	private int maxActive;
	@Value("${template.dataSource0.maxWait}")
	private int maxWait;
	@Value("${template.dataSource0.timeBetweenEvictionRunsMillis}")
	private int timeBetweenEvictionRunsMillis;
	@Value("${template.dataSource0.minEvictableIdleTimeMillis}")
	private int minEvictableIdleTimeMillis;
	@Value("${template.dataSource0.validationQuery}")
	private String validationQuery;
	@Value("${template.dataSource0.testWhileIdle}")
	private boolean testWhileIdle;
	@Value("${template.dataSource0.testOnBorrow}")
	private boolean testOnBorrow;
	@Value("${template.dataSource0.testOnReturn}")
	private boolean testOnReturn;
	@Value("${template.dataSource0.poolPreparedStatements}")
	private boolean poolPreparedStatements;
	@Value("${template.dataSource0.maxPoolPreparedStatementPerConnectionSize}")
	private int maxPoolPreparedStatementPerConnectionSize;
	@Value("${template.dataSource0.removeAbandoned}")
	private boolean removeAbandoned;
	@Value("${template.dataSource0.removeAbandonedTimeout}")
	private int removeAbandonedTimeout;
	@Value("${template.dataSource0.logAbandoned}")
	private boolean logAbandoned;
	@Value("${template.dataSource0.filters}")
	private String filters;

	@Bean(name = "dataSource0")
	public DataSource dataSource0() {
		DruidDataSource datasource0 = new DruidDataSource();
		datasource0.setUrl(this.dbUrl);
		datasource0.setUsername(username);
		datasource0.setPassword(password);

		// configuration
		datasource0.setInitialSize(initialSize);
		datasource0.setMinIdle(minIdle);
		datasource0.setMaxActive(maxActive);
		datasource0.setMaxWait(maxWait);
		datasource0.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
		datasource0.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
		datasource0.setValidationQuery(validationQuery);
		datasource0.setTestWhileIdle(testWhileIdle);
		datasource0.setTestOnBorrow(testOnBorrow);
		datasource0.setTestOnReturn(testOnReturn);
		datasource0.setPoolPreparedStatements(poolPreparedStatements);
		datasource0.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
		datasource0.setRemoveAbandoned(removeAbandoned);
		datasource0.setRemoveAbandonedTimeout(removeAbandonedTimeout);
		datasource0.setLogAbandoned(logAbandoned);
		try {
			datasource0.setFilters(filters);
		} catch (SQLException e) {
			logger.error("druid configuration initialization filter: " + e);
		}
		// 取消自动提交
		datasource0.setDefaultAutoCommit(false);
		return datasource0;
	}
	
	@Bean
	public MyTenantInfoHolder myTenantInfoHolder() {
		MyTenantInfoHolder myTenantInfoHolder = new MyTenantInfoHolder();
		return myTenantInfoHolder;
	}
	
	@Bean(name = "dataSource")
	public TenantAwareDataSource dataSource() {
		TenantAwareDataSource tenantAwareDataSource = new TenantAwareDataSource(myTenantInfoHolder());
		Map<Object, DataSource> dataSources = new HashMap<Object, DataSource>();
		dataSources.put("dataSource0", dataSource0());
		tenantAwareDataSource.setDataSources(dataSources);
		return tenantAwareDataSource;
	}

	@Bean(name = "transactionManager")
	public DataSourceTransactionManager transactionManager() {
		DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
		dataSourceTransactionManager.setDataSource(dataSource());
		return dataSourceTransactionManager;
	}
}
