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

import com.google.common.collect.ImmutableList;
import org.apache.commons.math3.random.RandomGenerator;

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.State;
import pl.edu.pw.mini.jk.sg.game.common.TwoPlayerPayoffInfo;
import pl.edu.pw.mini.jk.sg.game.common.advanceable.AdvanceableAttackerState;
import pl.edu.pw.mini.jk.sg.game.common.advanceable.AdvanceableDefenderState;

public interface DefenderAttackerGame<AM, DM extends DefenderMove, AS extends AdvanceableAttackerState<AM>, DS extends AdvanceableDefenderState<DM>, S extends State<AS, DS>> extends SecurityGame {
    S getCurrentState();

    void playDefenderMove(DM desiredConfigurationMove);

    void playAttackerMove(AM desiredConfigurationMove);

    AS getAttackerInitialState();

    DS getDefenderInitialState();

    TwoPlayerPayoffInfo finishRound();

    double getDefenderResult();

    double getAttackerResult();

    default AS getAttackerState() {
	return getCurrentState().getAttackerVisibleState();
    }

default DS getDefenderState() {
    return getCurrentState().getDefenderVisibleState();
}

    default ImmutableList<DM> possibleDefenderMoves() {
        return getCurrentState().getDefenderVisibleState().getPossibleMoves();
    }

    public default DM randomDefenderMove(RandomGenerator rng) {
	return getCurrentState().getDefenderVisibleState().getRandomMove(rng);
    }

    public default AM randomAttackerMove(RandomGenerator rng) {
	return getCurrentState().getAttackerVisibleState().getRandomMove(rng);
    }
    
    default ImmutableList<AM> possibleAttackerMoves() {
        return getCurrentState().getAttackerVisibleState().getPossibleMoves();
    }

}
