
package de.ivu.elect.business.stimmeingabe.boundary;

import java.io.Serializable;

import de.ivu.elect.business.ergebnis.entity.Ergebnis;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingabestatus;
import de.ivu.elect.business.stimmeingabe.entity.ErgebniseingabestatuswechelPruefergebnis;

public class ErgebniseingabestatuswechelPruefer implements Serializable {

  private static final long serialVersionUID = 1L;

  public ErgebniseingabestatuswechelPruefer() {
    super();
  }

  public ErgebniseingabestatuswechelPruefergebnis isStatusuebergangMoeglich(Ergebnis ergebnis, Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Ergebniseingabestatus ergebniseingabestatusZuSetzen,
      boolean freigabeZuruecknehmenRechtVorhanden) {
    Ergebniseingabestatus ergebniseingabestatus = getErgebniseingabestatus(ergebnis, wahldurchfuehrungsgebiet);

    if (ergebniseingabestatus.isFreigegeben()) {
      if (/* ELECT-8619 */!freigabeZuruecknehmenRechtVorhanden || /* ELECT-8621
       */isWahlBerichtetAnUebergeordneteWahl(wahldurchfuehrungsgebiet) && /*ELECT-11039*/isOberstesGebietFreigegeben(ergebnis, wahldurchfuehrungsgebiet)) {
        return ErgebniseingabestatuswechelPruefergebnis.NICHT_MOEGLICH;
      }
    }

    if (ergebniseingabestatus.getFolgeStatus().contains(ergebniseingabestatusZuSetzen)) {
      return ErgebniseingabestatuswechelPruefergebnis.MOEGLICH;
    }

    return ErgebniseingabestatuswechelPruefergebnis.NICHT_MOEGLICH;
  }

  private boolean isOberstesGebietFreigegeben(Ergebnis ergebnis, Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getErgebniseingabestatus(ergebnis, bestimmeOberstesGebiet(wahldurchfuehrungsgebiet)).isFreigegeben();

  }

  private Wahldurchfuehrungsgebiet bestimmeOberstesGebiet(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    Gebiet uebergeordnetesGebiet = wahldurchfuehrungsgebiet.getUebergeordnetesGebiet();
    if (uebergeordnetesGebiet == null) {
      return wahldurchfuehrungsgebiet;
    }
    return bestimmeOberstesGebiet(uebergeordnetesGebiet.castTo(Wahldurchfuehrungsgebiet.class).getEntity());
  }

  private boolean isWahlBerichtetAnUebergeordneteWahl(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return wahldurchfuehrungsgebiet.getWahl().getBerichtetAn() != null;
  }

  protected Ergebniseingabestatus getErgebniseingabestatus(Ergebnis ergebnis, Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return wahldurchfuehrungsgebiet.getErgebniseingabestatus(ergebnis);
  }
}
