package pl.edu.pw.mini.jk.sg.game.graph;

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

import pl.edu.pw.mini.jk.sg.game.common.AbstractGame;
import pl.edu.pw.mini.jk.sg.game.common.DefenderMove;
import pl.edu.pw.mini.jk.sg.game.common.State;
import pl.edu.pw.mini.jk.sg.game.configuration.StaticGameConfiguration;

public abstract class AbstractStaticGraphGame<DM extends DefenderMove,S extends State<?,?>> extends AbstractGame<DM, S> {
    private final StaticGameConfiguration staticGameConfiguration;
    private final ImmutableList<ImmutableSet<Integer>> possibleTargetFromVertex;

    public AbstractStaticGraphGame(AbstractStaticGraphGame<DM, S> game) {
	super(game);
	this.staticGameConfiguration = game.staticGameConfiguration;
	this.possibleTargetFromVertex = game.possibleTargetFromVertex;
    }
    
    public AbstractStaticGraphGame(StaticGameConfiguration staticGameConfiguration) {
        super(staticGameConfiguration.getDefenderCount(), staticGameConfiguration.getHistoryTimeHorizon());
        this.staticGameConfiguration = staticGameConfiguration;
        this.possibleTargetFromVertex = staticGameConfiguration.getPossibleTargetFromVertex();
    }

    protected double defenseSuccessProbability(int vertex, int defenders) {
        return staticGameConfiguration.getDefenseProbabilityFunc().apply(vertex, defenders);
    }

    @Override
    public double getAttackerReward(int target, int attacker) {
	return staticGameConfiguration.getAttackerReward(target, attacker);
    }

    @Override
    public double getDefenderPenalty(int target, int attacker) {
	return staticGameConfiguration.getDefenderPenalty(target, attacker);
    }

    public double vertexAttackerPenalty(int vertex, int attacker) {
        return staticGameConfiguration.getVertexAttackerPenalty(vertex, attacker);
    }

    @Override
    public double getDefenseEfficiency(int target, int defenderCount) {
        return defenseSuccessProbability(staticGameConfiguration.getTargets().get(target), defenderCount);
    }

    public double vertexDefenderReward(int vertex, int attacker) {
        return staticGameConfiguration.getVertexDefenderReward(vertex, attacker);
    }

    // @Override
    // public int getTargetCount() {
    //     return staticGameConfiguration.getTargets().size();
    // }

    @Override
    public double getAttackerPenalty(int target, int attacker) {
        return vertexAttackerPenalty(staticGameConfiguration.getTargets().get(target), attacker);
    }

    @Override
    public double getDefenderReward(int target, int attacker) {
        return vertexDefenderReward(staticGameConfiguration.getTargets().get(target), attacker);
    }


    public StaticGameConfiguration getStaticGameConfiguration() {
        return staticGameConfiguration;
    }
    
    public ImmutableList<ImmutableSet<Integer>> getPossibleTargetFromVertex() {
        return possibleTargetFromVertex;
    }
    
}
