package io.pddl.datasource.support.strategy;

import java.util.List;
import java.util.Random;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.CollectionUtils;

import io.pddl.datasource.support.WeightDataSourceProxy;
import io.pddl.datasource.PartitionDataSource;
import io.pddl.datasource.DataSourceReadStrategy;
import io.pddl.datasource.support.PartitionDataSourceSupport;

public class WeightReadStrategySupport implements DataSourceReadStrategy{
	
	private Log logger = LogFactory.getLog(getClass());
	
	@Override
	public DataSource getSlaveDataSource(PartitionDataSource pds) {
		return getDataSourceByWeight(pds,0);
	}
	
	protected DataSource getDataSourceByWeight(PartitionDataSource pds,int w){
		List<DataSource> slaveDataSources= ((PartitionDataSourceSupport)pds).getSlaveDataSources();
		if(CollectionUtils.isEmpty(slaveDataSources)){
			if(logger.isInfoEnabled()){
				logger.info("SlaveDataSource array of PartitionDataSource ["+pds.getName()+"] is empty, will use MasterDataSource");
			}
			return pds.getMasterDataSource();
		}
    	int total= 0;
    	//TODO this need cache
		for(DataSource ds: slaveDataSources){
			total+= ((WeightDataSourceProxy)ds).getWeight();
		}
		Random rand = new Random();
		int weight= 0,rdm= rand.nextInt(total+ w);
		for(DataSource ds: slaveDataSources){
			weight+= ((WeightDataSourceProxy)ds).getWeight();
			if(weight> rdm){
				if(logger.isInfoEnabled()){
					logger.info("found SlaveDataSource of PartitionDataSource ["+pds.getName()+"], weight: "+((WeightDataSourceProxy)ds).getWeight());
				}
				return ds;
			}
		}
		return pds.getMasterDataSource();
    }
	
	@Override
	public String getStrategyName(){
		return "weight";
	}

}

@@ -598,16 +598,47 @@
 lass());
+%0A%0A%09private int totalWeight = 0;
 %0A%09%0A%09@Ove
@@ -1173,151 +1173,108 @@
 %09%09%7D%0A
-    %09int total= 0;%0A    %09//TODO this need cache%0A%09%09for(DataSource ds: slaveDataSources)%7B%0A%09%09%09total+= ((WeightDataSourceProxy)ds).getWeight(
+%0A%09%09if (totalWeight == 0) %7B%0A%09%09%09// cache total weight%0A%09%09%09calculateTotalWeight(slaveDataSources
 );%0A%09%09%7D%0A
+%0A
 %09%09Ra
@@ -1338,16 +1338,23 @@
 nt(total
+Weight 
 + w);%0A%09%09
@@ -1751,16 +1751,16 @@
 Name()%7B%0A
-
 %09%09return
@@ -1774,10 +1774,242 @@
 t%22;%0A%09%7D%0A%0A
+%09private synchronized void calculateTotalWeight(List%3CDataSource%3E lds) %7B%0A%09%09if (totalWeight != 0) return;%0A%0A%09%09int total = 0;%0A%09%09for(DataSource ds: lds)%7B%0A%09%09%09total+= ((WeightDataSourceProxy)ds).getWeight();%0A%09%09%7D%0A%09%09totalWeight = total;%0A%09%7D%0A%0A
 %7D%0A

add cache