package kickr.util;
import java.util.EnumMap;
import java.util.Map;
import kickr.db.entity.Game;
import kickr.db.entity.Match;
import static kickr.util.Side.*;
/**
*
* @author nikku
*/
public class MatchResultDetails {
private static final int CLOSE_DIFFERENCE = 2;
private static final int STOMP_MIN_SUM = 7;
private static final int STOMP_MAX_LOSS_GOALS = 1;
private final Match match;
private final Map<Side, Integer> wins;
private final Map<Side, Integer> goals;
private final Map<Side, Integer> stomps;
private final Map<Side, Integer> closeLosses;
private int totalGames = 0;
private int ties = 0;
public MatchResultDetails(Match match) {
this.match = match;
this.wins = new EnumMap<>(Side.class);
this.goals = new EnumMap<>(Side.class);
this.stomps = new EnumMap<>(Side.class);
this.closeLosses = new EnumMap<>(Side.class);
}
public int getTies() {
return ties;
}
public int getTotalGames() {
return totalGames;
}
public int getWins(Side side) {
return wins.getOrDefault(side, 0);
}
public boolean isTied() {
return !isWinner(TEAM1) && !isWinner(TEAM2);
}
public boolean isWinner(Side side) {
return getWins(side) > getWins(side.opposite());
}
public int getCloseLosses(Side side) {
return closeLosses.getOrDefault(side, 0);
}
public int getStomps(Side side) {
return stomps.getOrDefault(side, 0);
}
public Match getMatch() {
return match;
}
protected void add(Game game) {
Integer scoreTeam1 = game.getScoreTeam1();
Integer scoreTeam2 = game.getScoreTeam2();
Integer difference = Math.abs(scoreTeam1 - scoreTeam2);
Integer sum = scoreTeam1 + scoreTeam2;
addGoals(TEAM1, scoreTeam1);
addGoals(TEAM2, scoreTeam2);
totalGames++;
Side winner = null;
if (scoreTeam1 > scoreTeam2) {
winner = TEAM1;
}
if (scoreTeam1 < scoreTeam2) {
winner = TEAM2;
}
if (winner != null) {
addWin(winner);
if (difference <= CLOSE_DIFFERENCE) {
addCloseLoss(winner.opposite());
}
if (sum > STOMP_MIN_SUM && sum - difference <= STOMP_MAX_LOSS_GOALS) {
addStomp(winner);
}
} else {
ties++;
}
}
private void addGoals(Side side, Integer sideGoals) {
goals.merge(side, sideGoals, Integer::sum);
}
private void addWin(Side side) {
wins.merge(side, 1, Integer::sum);
}
private void addCloseLoss(Side side) {
closeLosses.merge(side, 1, Integer::sum);
}
private void addStomp(Side side) {
stomps.merge(side, 1, Integer::sum);
}
// static helpers
public static MatchResultDetails compute(Match match) {
MatchResultDetails matchResultDetails = new MatchResultDetails(match);
match.getGames().stream().forEach(matchResultDetails::add);
return matchResultDetails;
}
}