
package de.ivu.elect.sitzberechnung.verteilung;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

import de.ivu.elect.sitzberechnung.control.Sitzberechnungsdaten;
import de.ivu.elect.sitzberechnung.entity.DefaultSitzberechnungsergebnis;
import de.ivu.elect.sitzberechnung.konflikt.ErgebnisKonflikt;

public abstract class AbstractErgebnisKonfliktFactory {

  private final Sitzberechnungsdaten sitzberechnungsdaten;

  private final DefaultSitzberechnungsergebnis sitzberechnungsergebnis;

  protected AbstractErgebnisKonfliktFactory(Sitzberechnungsdaten sitzberechnungsdaten, DefaultSitzberechnungsergebnis sitzberechnungsergebnis) {
    super();

    this.sitzberechnungsdaten = sitzberechnungsdaten;
    this.sitzberechnungsergebnis = sitzberechnungsergebnis;
  }

  @SuppressWarnings("unchecked")
  protected <K extends ErgebnisKonflikt> K createOrFindErgebnisKonflikt(K ergebnisKonflikt) {
    K result = (K) sitzberechnungsdaten.getFachlichenGleichenKonflikt(ergebnisKonflikt).orElse(ergebnisKonflikt);
    sitzberechnungsergebnis.addKonflikt(result);

    return result;
  }

  @SuppressWarnings("unchecked")
  protected <O, T extends AbstractTeilnehmer<O>> List<O> filterTeilnehmerImLosverfahren(Function<AbstractTeilnehmer< ? >, TeilnehmerErgebnis> teilnehmerErgebnisFct, List<T> teilnehmerInVerteilung) {
    List<O> auswaehlbar = new ArrayList<>();

    for (AbstractTeilnehmer< ? > teilnehmer : teilnehmerInVerteilung) {
      TeilnehmerErgebnis teilnehmerErgebnis = teilnehmerErgebnisFct.apply(teilnehmer);

      if (teilnehmerErgebnis != null && isImLosverfahren(teilnehmerErgebnis)) {
        auswaehlbar.add((O) teilnehmer.getObject());
      }
    }

    return auswaehlbar;
  }

  protected boolean isImLosverfahren(TeilnehmerErgebnis teilnehmerErgebnis) {
    return teilnehmerErgebnis != null && !teilnehmerErgebnis.isEntschieden() && teilnehmerErgebnis.isTeilnehmerAmLosverfahren();
  }
}
