package pl.edu.pw.mini.sg.gamegen;

import java.io.File;
import java.io.IOException;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Preconditions;

public class BuildingLikeGameGeneratorConfig {
    private final BuildingDimensions dimensions;
    private final int elevatorCount;
    private final int targetCount;
    private final double doorDensity;
    private final double interiorDensity;
    private final int attackerCaughtPenaltyTarget;
    private final int attackerCaughtPenaltyNormal;
    private final int defenderSuccessRewardTarget;
    private final int defenderSuccessRewardNormal;
    private final int defenderPenaltyBound;
    private final int attackerRewardBound;
    private final int numberOfAttackers;
    private final int numberOfDefenders;
    private final boolean zeroSum;

    @JsonCreator
    public BuildingLikeGameGeneratorConfig(@JsonProperty("buildingDimensions") BuildingDimensions dimensions,
            @JsonProperty("elevatorCount") int elevatorCount, @JsonProperty("targetCount") int targetCount,
            @JsonProperty("doorDensity") double doorDensity, @JsonProperty("interiorDensity") double interiorDensity,
            @JsonProperty("attackerCaughtPenaltyTarget") int attackerCaughtPenaltyTarget,
            @JsonProperty("attackerCaughtPenaltyNormal") int attackerCaughtPenaltyNormal,
            @JsonProperty("defenderSuccessRewardTarget") int defenderSuccessRewardTarget,
            @JsonProperty("defenderSuccessRewardNormal") int defenderSuccessRewardNormal,
            @JsonProperty("defenderPenaltyBound") int defenderPenaltyBound,
            @JsonProperty("attackerRewardBound") int attackerRewardBound,
            @JsonProperty("numberOfAttackers") int numberOfAttackers,
					   @JsonProperty("numberOfDefenders") int numberOfDefenders,
					   @JsonProperty("zeroSum") boolean zeroSum) {
        super();
	Preconditions.checkState(!zeroSum || (attackerCaughtPenaltyTarget == defenderSuccessRewardTarget &&
					      defenderSuccessRewardNormal == attackerCaughtPenaltyNormal),
				 "given values are not sero sum!");
        this.dimensions = Preconditions.checkNotNull(dimensions);
        this.elevatorCount = elevatorCount;
        this.targetCount = targetCount;
        this.doorDensity = doorDensity;
        this.interiorDensity = interiorDensity;
        this.attackerCaughtPenaltyTarget = attackerCaughtPenaltyTarget;
        this.attackerCaughtPenaltyNormal = attackerCaughtPenaltyNormal;
        this.defenderSuccessRewardTarget = defenderSuccessRewardTarget;
        this.defenderSuccessRewardNormal = defenderSuccessRewardNormal;
        this.defenderPenaltyBound = defenderPenaltyBound;
        this.attackerRewardBound = attackerRewardBound;
        this.numberOfAttackers = numberOfAttackers;
        this.numberOfDefenders = numberOfDefenders;
	this.zeroSum = zeroSum;
    }

    public static BuildingLikeGameGeneratorConfig parse(File input) throws JsonProcessingException, IOException {
        final ObjectMapper mapper = new ObjectMapper();
        return mapper.reader(BuildingLikeGameGeneratorConfig.class).readValue(input);
    }

    public BuildingDimensions getDimensions() {
        return dimensions;
    }

    public int getElevatorCount() {
        return elevatorCount;
    }

    public int getTargetCount() {
        return targetCount;
    }

    public double getDoorDensity() {
        return doorDensity;
    }

    public double getInteriorDensity() {
        return interiorDensity;
    }

    public int getAttackerCaughtPenaltyTarget() {
        return attackerCaughtPenaltyTarget;
    }

    public int getAttackerCaughtPenaltyNormal() {
        return attackerCaughtPenaltyNormal;
    }

    public int getDefenderSuccessRewardTarget() {
        return defenderSuccessRewardTarget;
    }

    public int getDefenderSuccessRewardNormal() {
        return defenderSuccessRewardNormal;
    }

    public int getDefenderPenaltyBound() {
        return defenderPenaltyBound;
    }

    public int getAttackerRewardBound() {
        return attackerRewardBound;
    }

    public int getNumberOfAttackers() {
        return numberOfAttackers;
    }

    public int getNumberOfDefenders() {
        return numberOfDefenders;
    }

    public boolean isZeroSum() {
	return zeroSum;
    }
}
