package pl.edu.pw.mini.jk.sg.gteval;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import pl.edu.pw.mini.jk.sg.game.common.Cloneable;

import pl.edu.pw.mini.jk.sg.game.common.DefenderMove;
import pl.edu.pw.mini.jk.sg.game.common.SecurityGame;
import pl.edu.pw.mini.jk.sg.game.common.advanceable.AdvanceableAttackerState;
import pl.edu.pw.mini.jk.sg.game.common.advanceable.AdvanceableDefenderState;
import pl.edu.pw.mini.jk.sg.game.DefenderAttackerGame;
import pl.edu.pw.mini.jk.sg.gteval.result.TimedTrainingResult;
import pl.edu.pw.mini.jk.sg.gteval.result.TimedTrainingResultFactory;
import pl.edu.pw.mini.jk.sg.mixeduct.attackerresponse.OptimalAttacker;

public class UniformPlayer {

	public static <DM extends DefenderMove, AM, AS extends AdvanceableAttackerState<AM>, DS extends AdvanceableDefenderState<DM>, G extends Cloneable<G> & SecurityGame & DefenderAttackerGame<AM, DM, AS, DS, ?>> TimedTrainingResultFactory<DM, AM> uniformPlayer(
			final GameMatrices<AM, DM, AS, DS, G> gameMatrices) {
		final List<ImmutableList<DM>> defenderSequences2 = gameMatrices.getDefenderSequences();
		final Map<ImmutableList<DM>, Double> bestDefenderStrategy = defenderSequences2.stream()
		.collect(Collectors.toMap(e -> e, e -> 1.0 / defenderSequences2.size()));
	
		ImmutableMap<ImmutableList<AM>, Double> amp = OptimalAttacker
		.solveAttackerOptimalStrategy(gameMatrices, bestDefenderStrategy);
	
		final double normCoeff = bestDefenderStrategy.values().stream().mapToDouble(i -> i).sum();
		Map<ImmutableList<DM>, Double> dmp = bestDefenderStrategy.entrySet().stream()
		.collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue() / normCoeff));
		
		return x -> new TimedTrainingResult<>(ImmutableMap.copyOf(dmp), ImmutableMap.copyOf(amp), gameMatrices, x);
	}

}
