package pl.edu.pw.mini.jk.lib;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.DoubleFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.commons.math3.util.Pair;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

public final class PmfUtils {
	private PmfUtils() {}

	public static String pmfToSortedString(Map<?, Double> pmf, Optional<Integer> precission) {
		final double pSum = pmf.values().stream().mapToDouble(i -> i).sum();
		return pmfToSortedString(pmf.entrySet().stream().map(e -> new Pair<>(e.getKey(), e.getValue()/pSum)), precission);
	}

	public static String pmfToSortedString(Stream<? extends Pair<?, Double>> pmf, Optional<Integer> precission) {
		final DoubleFunction<String> formatter = precission.<DoubleFunction<String>>map(p -> new DoubleFunction<String>() {
			@Override
			public String apply(double value) {
				return String.format("%."+p+"f", value);
			}
		}).orElse(Double::toString);
		return pmf.sorted(Comparator.<Pair<?, Double>, Double>comparing(Pair::getSecond).reversed())
				.map(p -> p.getFirst().toString() + "=" + formatter.apply(p.getSecond())).collect(Collectors.joining(", "));
	}

	public static String pmfToSortedString(List<? extends Pair<?, Double>> pmf, Optional<Integer> precission) {
		return pmfToSortedString(pmf.stream(), precission);
	}

    public static <M> ImmutableMap<ImmutableList<M>, Double> normalizeStrategy(Map<ImmutableList<M>, Double> strategy) {
	final double sum = strategy.values().stream().mapToDouble(x -> x).sum();
	return ImmutableMap.copyOf(strategy.entrySet().stream().collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue()/sum)));
    }
}
