
package de.ivu.elect.sitzberechnung.verteilung;

import static java.util.stream.Collectors.toList;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import javax.annotation.Nullable;

public abstract class AbstractReihenfolgeErgebnis {

  private final List<TeilnehmerErgebnis> teilnehmerErgebnisse;

  private final List<TeilnehmerErgebnis> teilnehmerErgebnisseSortiert;

  protected AbstractReihenfolgeErgebnis(List< ? extends Teilnehmer> teilnehmer) {
    super();

    this.teilnehmerErgebnisse = teilnehmer.stream().map(TeilnehmerErgebnis::new).collect(toList());
    this.teilnehmerErgebnisse.forEach(TeilnehmerErgebnis::seiTeilnehmerAmLosverfahren); // Alle Teilnehmer in der Sortierung sind auch Teilnehmer am Losverfahren...

    this.teilnehmerErgebnisseSortiert = new ArrayList<>();

    if (teilnehmer.size() < 2) {
      entscheideLosverfahren(teilnehmer);
    }
  }

  /**
   * @return <code>true</code>, wenn die Reihenfolge entschieden ist, andernfalls <code>false</code>
   */
  public boolean isEntschieden() {
    for (TeilnehmerErgebnis teilnehmerErgebnis : teilnehmerErgebnisse) {
      if (!teilnehmerErgebnis.isEntschieden()) {
        return false;
      }
    }

    return true;
  }

  public void entscheideLosverfahren(List< ? extends Teilnehmer> teilnehmerSortiert) {
    teilnehmerErgebnisseSortiert.clear();

    for (Teilnehmer teilnehmer : teilnehmerSortiert) {
      TeilnehmerErgebnis teilnehmerErgebnis = getTeilnehmerErgebnis(teilnehmer);

      if (teilnehmerErgebnis != null) {
        teilnehmerErgebnis.entscheideLosverfahren(1L); // Setzt alle notwendigen Zauber-Schalter...

        teilnehmerErgebnisseSortiert.add(teilnehmerErgebnis);
      }
    }
  }

  @Nullable
  public TeilnehmerErgebnis getTeilnehmerErgebnis(Teilnehmer teilnehmer) {
    for (TeilnehmerErgebnis teilnehmerErgebnis : teilnehmerErgebnisse) {
      if (Objects.equals(teilnehmerErgebnis.getTeilnehmer(), teilnehmer)) {
        return teilnehmerErgebnis;
      }
    }

    return null;
  }

  public List<TeilnehmerErgebnis> getTeilnehmerErgebnisse() {
    if (isEntschieden()) {
      return teilnehmerErgebnisseSortiert;
    }

    return teilnehmerErgebnisse;
  }

  @Override
  public String toString() {
    return getClass().getSimpleName() + "(" + teilnehmerErgebnisse + ")";
  }
}
