
package de.ivu.elect.business.wahl.entity;

import java.util.Date;

import javax.annotation.Nullable;

import de.ivu.elect.business.benutzerverwaltung.entity.Rolle;
import de.ivu.elect.business.gebietsbaum.control.EntityMitWurzelgebiet;
import de.ivu.elect.business.mandant.entity.EntityMitMandant;
import de.ivu.elect.business.mandant.entity.Mandant;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.security.control.ElectCommonPrincipal;
import de.ivu.elect.jee.entity.EntityContainer;

public interface WahlOderWahltermin extends EntityMitMandant, EntityMitWurzelgebiet {

  // NOTE ELECT-5319, dass nicht Entity#isWahltermin definiert werden kann, da dieser Methodenname bei Verwendung von EL in
  // den XHTML-Seiten bspw. mit Wahl#getWahltermin clashed!
  boolean isInstanceOfWahltermin();

  boolean isInstanceOfWahl();

  Rolle getEinsehenRolle();

  void setEinsehenRolle(Rolle einsehenRolle);

  boolean isPersistent();

  String getName();

  Date getWahldatum();

  String getWahlterminNummer();

  int getWahljahr();

  Date getStichwahlWahldatum();

  String getEinsehenRolleMessageKey();

  boolean isWahldatumNichtFestgelegt();

  <E> EntityContainer<E> castTo(Class<E> var1);

  default String getEinsehenRolleName() {
    if (getEinsehenRolle() == null) {
      return "";
    }

    return getEinsehenRolle().getName();
  }

  default boolean isRechtZumEinsehenVorhanden(ElectCommonPrincipal principal) {
    return principal.hasUseCasePermission(UseCasePermission.WAHL_ALLE_EINSEHEN) || principal.hatRolle(getEinsehenRolleName());
  }

  default boolean isMandantStimmtUeberein(ElectCommonPrincipal principal) {
    return getMandant() != null && getMandant().equals(principal.getMandant());
  }

  @Nullable
  default Wahl getWahlIfWahl() {
    if (isInstanceOfWahl()) {
      return castTo(Wahl.class).getEntity();
    }

    if (isInstanceOfWahltermin()) {
      return null;
    }

    throw new IllegalStateException();
  }

  @Nullable
  default Wahltermin getWahlterminIfWahltermin() {
    if (isInstanceOfWahl()) {
      return castTo(Wahl.class).getEntity().getWahltermin();
    }

    if (isInstanceOfWahltermin()) {
      return castTo(Wahltermin.class).getEntity();
    }

    throw new IllegalStateException();
  }

  @Override
  // Methode muss vorhanden bleiben, um die default Implementierung aus EntityMitMandant zu überschreiben
  Mandant getMandant();

  static WahlOderWahltermin from(Wahltermin wahltermin, Wahl wahl) {
    if (wahl != null) {
      return wahl;
    }

    return wahltermin;
  }

  default WahlOderWahlterminPK getWahlOderWahlterminPK() {
    if (isInstanceOfWahl()) {
      return new WahlOderWahlterminPK(getWahlIfWahl().getPk());
    }

    if (isInstanceOfWahltermin()) {
      return new WahlOderWahlterminPK(getWahlterminIfWahltermin().getPk());
    }

    throw new IllegalStateException();
  }
}
