package eu.dnetlib.data.function;

import java.util.List;

import org.apache.commons.lang.math.RandomUtils;

import com.google.common.base.Function;
import com.google.common.collect.Lists;

public class OneCharErrWeight implements Function<String, String> {

	public static int maxBoost = 100;
	
	private int boostFirstChar;
	
	public OneCharErrWeight(int boostFistChar) {
		this.boostFirstChar = boostFistChar;
	}
	
	@Override
	public String apply(String s) {
		
		List<Weighting> weights = Lists.newArrayList(new Weighting(0, boostFirstChar));
		for(int i=1; i<s.length(); i++) {
			weights.add(new Weighting(i, (maxBoost - boostFirstChar) / (s.length() - 1)));
		}
		
		//int i = RandomUtils.nextInt(s.length());
		int i = weightedRandom(weights);
		char[] a = s.toCharArray();
		
		char t = a[i];
		while(t == a[i])
			t = (char)(RandomUtils.nextInt(26) + 'a');
		a[i] = t;
		
		return new String(a);
	}
	
	class Weighting {

	    int value;
	    int weight;

	    public Weighting(int v, int w) {
	        this.value = v;
	        this.weight = w;
	    }
	}

	private int weightedRandom(List<Weighting> weights) {

	    //determine sum of all weightings
	    int total = 0;
	    for (Weighting w : weights) {
	        total += w.weight;
	    }

	    //select a random value between 0 and our total
	    int random = RandomUtils.nextInt(total);

	    //loop thru our weightings until we arrive at the correct one
	    int current = 0;
	    for (Weighting w : weights) {
	        current += w.weight;
	        if (random < current)
	            return w.value;
	    }

	    //shouldn't happen.
	    return -1;
	}	

}
