package com.uas.eis.core.config;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import java.util.UUID;

import javax.sql.DataSource;
 





import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.bind.RelaxedDataBinder;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.jdbc.core.JdbcTemplate;
 
/**
 * 动态数据源注册;
 */
public class DynamicDataSourceRegister  implements ImportBeanDefinitionRegistrar, EnvironmentAware {
   
	@Autowired
	JdbcTemplate jdbcTemplate;
	
    //如配置文件中未指定数据源类型，使用该默认值
    private static final Object DATASOURCE_TYPE_DEFAULT = "com.alibaba.druid.pool.DruidDataSource";
    private ConversionService conversionService = new DefaultConversionService();
    private PropertyValues dataSourcePropertyValues;
   
    // 默认数据源
    private DataSource defaultDataSource;
   
    private Map<String, DataSource> customDataSources = new HashMap<String, DataSource>();
   
    /**
     * 加载多数据源配置
     */
    @Override
    public void setEnvironment(Environment environment) {
    	initDefaultDataSource(environment);
    	initCustomDataSources(environment);
    }
   
    /**
     * 加载主数据源配置.
     * @param env
     */
    private void initDefaultDataSource(Environment env){
    	// 读取主数据源
    	RelaxedPropertyResolver propertyResolver = new RelaxedPropertyResolver(env, "spring.datasource.");
       
        Map<String, Object> dsMap = new HashMap<String, Object>();
        dsMap.put("type", propertyResolver.getProperty("type"));
        dsMap.put("driverClassName", propertyResolver.getProperty("driverClassName"));
        dsMap.put("url", propertyResolver.getProperty("url"));
        dsMap.put("username", propertyResolver.getProperty("username"));
        dsMap.put("password", propertyResolver.getProperty("password"));
        
        //创建数据源;
        defaultDataSource = buildDataSource(dsMap);
        dataBinder(defaultDataSource, env);
        customDataSources.put(propertyResolver.getProperty("username"), defaultDataSource);
    }
   
    /**
     * 初始化更多数据源
     *
     */
    private void initCustomDataSources(Environment env) {
        // 读取配置文件获取更多数据源，也可以通过defaultDataSource读取数据库获取更多数据源
    	/*DynamicDataSourceManage.setDataSourceType("UAS_DEV");
    	List<Map<String , Object>> master = jdbcTemplate.queryForList("select MA_USER,MA_PWD from master");
    	System.out.println(master);*/
    	JdbcTemplate jdbcTemplate = new JdbcTemplate(defaultDataSource);  
    	List<Map<String , Object>> master = jdbcTemplate.queryForList("select MA_USER,MS_PWD from master");
    	// 读取主数据源
        RelaxedPropertyResolver propertyResolver = new RelaxedPropertyResolver(env, "spring.datasource.");
    	for(Map<String , Object> map : master){
    		String ma_user = (String)map.get("MA_USER");
    		Map<String, Object> dsMap = new HashMap<>();
    		dsMap.put("type", propertyResolver.getProperty("type"));
            dsMap.put("driverClassName", propertyResolver.getProperty("driverClassName"));
            dsMap.put("url", propertyResolver.getProperty("url"));
            dsMap.put("password", propertyResolver.getProperty("password"));
            dsMap.put("username", ma_user);
            DataSource ds = buildDataSource(dsMap);
            customDataSources.put(ma_user, ds);
            dataBinder(ds, env);
    	}
    }
   
    /**
     * 创建datasource.
     * @param dsMap
     * @return
     */
    @SuppressWarnings("unchecked")
    public DataSource buildDataSource(Map<String, Object> dsMap) {
    	Object type = dsMap.get("type");
        if (type == null){
            type = DATASOURCE_TYPE_DEFAULT;// 默认DataSource
        }
        Class<? extends DataSource> dataSourceType;
       
       try {
           	dataSourceType = (Class<? extends DataSource>) Class.forName((String) type);
           	String driverClassName = dsMap.get("driverClassName").toString();
            String url = dsMap.get("url").toString();
            String username = dsMap.get("username").toString();
            String password = dsMap.get("password").toString();
            DataSourceBuilder factory =   DataSourceBuilder.create().driverClassName(driverClassName).url(url).username(username).password(password).type(dataSourceType);
            return factory.build();
       } catch (ClassNotFoundException e) {
           e.printStackTrace();
       }
       return null;
    }
   
    /**
     * 为DataSource绑定更多数据
     * @param dataSource
     * @param env
     */
    private void dataBinder(DataSource dataSource, Environment env){
    	RelaxedDataBinder dataBinder = new RelaxedDataBinder(dataSource);
    	dataBinder.setConversionService(conversionService);
    	dataBinder.setIgnoreNestedProperties(false);//false
        dataBinder.setIgnoreInvalidFields(false);//false
        dataBinder.setIgnoreUnknownFields(true);//true
       
        if(dataSourcePropertyValues == null){
            Map<String, Object> values = new HashMap<>();
            dataSourcePropertyValues = new MutablePropertyValues(values);
        }
        dataBinder.bind(dataSourcePropertyValues);
       
    }
   
 
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
       	Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
       	// 将主数据源添加到更多数据源中
        /*targetDataSources.put("dataSource", defaultDataSource);
        DynamicDataSourceManage.dataSourceIds.add("dataSource");*/
        // 添加更多数据源
        targetDataSources.putAll(customDataSources);
        // 创建DynamicDataSource
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        beanDefinition.setBeanClass(DynamicDataSource.class);
       
        beanDefinition.setSynthetic(true);
        MutablePropertyValues mpv = beanDefinition.getPropertyValues();
        //添加属性：AbstractRoutingDataSource.defaultTargetDataSource
        mpv.addPropertyValue("defaultTargetDataSource", defaultDataSource);
        mpv.addPropertyValue("targetDataSources", targetDataSources);
        registry.registerBeanDefinition("dataSource", beanDefinition);
    }
 
}