/**
 * 
 */
package org.springblade.datasource.support;

import com.baomidou.dynamic.datasource.creator.DataSourceProperty;
import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;
import com.baomidou.dynamic.datasource.creator.druid.DruidConfig;
import com.baomidou.dynamic.datasource.provider.AbstractJdbcDataSourceProvider;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import lombok.extern.slf4j.Slf4j;
import org.springblade.datasource.enums.DsTypeEnum;
import org.springblade.datasource.model.DatasourceDto;
import org.springblade.datasource.util.DatasourceUtil;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * @author wookvn
 *
 */
@Slf4j
public class BladexDataSourceProvider extends AbstractJdbcDataSourceProvider {
	
	private final DynamicDataSourceProperties dynamicDataSourceProperties;
	
	public BladexDataSourceProvider(DefaultDataSourceCreator defaultDataSourceCreator, DynamicDataSourceProperties dynamicDataSourceProperties, String url, String username, String password) {
		super(defaultDataSourceCreator, url, username, password);
		this.dynamicDataSourceProperties = dynamicDataSourceProperties;
	}
	
	@Override
	protected Map<String, DataSourceProperty> executeStmt(Statement statement) throws SQLException {
		log.info("开始初始化动态数据源");
		Map<String, DataSourceProperty> dsMap = new HashMap<String, DataSourceProperty>();
		ResultSet rs = statement.executeQuery("select * from report_datasource where is_deleted = 0");
		List<CompletableFuture<Boolean>> futureList = new ArrayList<CompletableFuture<Boolean>>();
		DruidConfig druid = dynamicDataSourceProperties.getDruid();
		while(rs.next()) {
			String poolName = rs.getString("pool_name"),
				   driverClassName = rs.getString("driver_class_name"),
				   url = rs.getString("url"),
				   dsUser = rs.getString("ds_user"),
				   dsPassword = rs.getString("ds_password"),
				   dsDbname = rs.getString("ds_db"),
				   customConnectProperties = rs.getString("custom_connect_properties");
			int dsType = rs.getInt("ds_type"),
			    id     = rs.getInt("id");
			futureList.add(CompletableFuture.supplyAsync(() -> {
				DataSourceProperty dataSourceProperty = new DataSourceProperty();
				dataSourceProperty.setPoolName(poolName);
				dataSourceProperty.setDriverClassName(driverClassName);
				dataSourceProperty.setUrl(url);
				dataSourceProperty.setUsername(dsUser);
				dataSourceProperty.setPassword(dsPassword);
				dataSourceProperty.setLazy(true);
				//校验连接成功，允许初始化添加到动态数据源
				DatasourceDto reportDs = new DatasourceDto();
				reportDs.setDsUser(dataSourceProperty.getUsername());
				reportDs.setDsPassword(dataSourceProperty.getPassword());
				reportDs.setUrl(dataSourceProperty.getUrl());
				reportDs.setDsTypeSyl(DsTypeEnum.resolve(dsType));
				reportDs.setCustomConnectProperties(customConnectProperties);
				if(DatasourceUtil.testDs(reportDs) == null) { //特殊处理一下数据源
					//设置jdbc驱动连接属性
					dataSourceProperty.setDruid(DatasourceUtil.customConnectionConfig(druid, reportDs));
					log.info(">>>>INIT_DS_SUCCESS|id={},type={},db={},validationQuery={}", id, reportDs.getDsTypeSyl().name(), dsDbname, reportDs.getDsTypeSyl().getValidationQuery());
					dsMap.put(poolName, dataSourceProperty);
					return true;
				}else {
					log.warn("####INIT_DS_FAILURE|id={},db={},dsType={}", id, dsDbname, reportDs.getDsTypeSyl());
					return false;
				}
			}));
		}
		CompletableFuture.allOf(futureList.stream().toArray(CompletableFuture[]::new)).join();
		log.info("数据源初始化完成");
		return dsMap;
	}
}
