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

import static java.util.Arrays.asList;
import static java.util.Arrays.stream;

import java.util.Collection;

import javax.annotation.Nullable;

import de.ivu.elect.business.ergebnis.entity.Ergebnis;
import de.ivu.elect.business.ergebnis.entity.Ergebnisart;
import de.ivu.elect.business.wahl.entity.WahlartErgebnisart;

public enum Ergebniseingangsart implements WahlartErgebnisart {

  VORLAEUFIG {

    @Override
    protected Collection<Ergebnisart> fliesstEinInErgebnisarten() {
      return asList(Ergebnisart.VORLAEUFIG/* , Ergebnisart.HOCHRECHNUNG_VORLAEUFIG */);
    }

    @Override
    public Ergebnisart korrespondierendeErgebnisart() {
      return Ergebnisart.VORLAEUFIG;
    }

    @Override
    public Ergebniseingangsart getArtNachWechsel() {
      return ENDGUELTIG;
    }
  },
  ENDGUELTIG {

    @Override
    protected Collection<Ergebnisart> fliesstEinInErgebnisarten() {
      return asList(Ergebnisart.ENDGUELTIG/* , Ergebnisart.HOCHRECHNUNG_ENDGUELTIG */);
    }

    @Override
    public Ergebnisart korrespondierendeErgebnisart() {
      return Ergebnisart.ENDGUELTIG;
    }

    @Override
    public Ergebniseingangsart getArtNachWechsel() {
      return VORLAEUFIG;
    }
  };

  protected abstract Collection<Ergebnisart> fliesstEinInErgebnisarten();

  public abstract Ergebnisart korrespondierendeErgebnisart();

  /**
   * Methode ist an dieser enum und nicht an Ergebnisart, da Ergebnisart in CORE liegt und Ergebniseingangsart in WAS
   */
  public static Ergebniseingangsart getErgebniseingangsartFuerErgebnisArt(Ergebnisart ergebnisart) {
    for (Ergebniseingangsart ergebniseingangsart : Ergebniseingangsart.values()) {
      if (ergebniseingangsart.fliesstEinInErgebnisarten().contains(ergebnisart)) {
        return ergebniseingangsart;
      }
    }

    throw new IllegalStateException("Keine Ergebniseingangsart für Ergebnisart: " + ergebnisart);
  }

  @Nullable
  public static Ergebniseingangsart getKorrespondierendeErgebniseingangsart(Ergebnis ergebnis) {
    if (ergebnis != null) {
      return getKorrespondierendeErgebniseingangsart(ergebnis.getErgebnisart());
    }

    return null;
  }

  @Nullable
  public static Ergebniseingangsart getKorrespondierendeErgebniseingangsart(WahlartErgebnisart ergebnisart) {
    return stream(values()).filter(ergebniseingangsart -> ergebniseingangsart.korrespondierendeErgebnisart().equals(ergebnisart)).findFirst().orElse(null);
  }

  @Override
  public boolean isEndgueltig() {
    return ENDGUELTIG.equals(this);
  }

  @Override
  public boolean isVorlaeufig() {
    return VORLAEUFIG.equals(this);
  }

  public abstract Ergebniseingangsart getArtNachWechsel();
}
