
package de.ivu.elect.business.sitzberechnung.control.wahlneutral;

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

import java.util.List;

import de.ivu.elect.business.ergebnis.control.ErgebnisDatenQuorum;
import de.ivu.elect.business.gebietsbaum.control.GebietByPositionComparator;
import de.ivu.elect.business.gebietsbaum.entity.AbstractGebiet;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.kandidatur.entity.Direktkandidatur;
import de.ivu.elect.business.sitzberechnung.entity.SitzberechnungsalgorithmusKonfiguration;
import de.ivu.elect.business.sitzberechnung.entity.Sitzberechnungseingabe;
import de.ivu.elect.business.sitzberechnung.entity.Sitzberechnungsergebnis;
import de.ivu.elect.util.NotNull;

public interface MehrheitswahlSitzberechnungsalgorithmusInternal<K extends SitzberechnungsalgorithmusKonfiguration> {

  Sitzberechnungsergebnis berechneSitzverteilung();

  default List<Wahldurchfuehrungsgebiet> collectDirektwahlgebiete(Sitzberechnungseingabe<K> sitzberechnungseingabe) {
    return sitzberechnungseingabe.getStimmergebnisDaten().getGebiete(AbstractGebiet::isDirektwahlgebiet).stream().sorted(new GebietByPositionComparator()::compare).collect(toList());
  }

  default List<Direktkandidatur> collectDirektkandidaturen(Sitzberechnungseingabe<K> sitzberechnungseingabe, Wahldurchfuehrungsgebiet direktwahlgebiet) {
    return sitzberechnungseingabe.getStimmergebnisDaten().getDirektkandidaturenNachGebiet(direktwahlgebiet);
  }

  default long getAnzahlStimmen(Sitzberechnungseingabe<K> sitzberechnungseingabe, Direktkandidatur direktkandidatur) {
    return NotNull.notNull(sitzberechnungseingabe.getAnzahlStimmenFuerDirektkandidaturKumuliertBisGebietAufDemKandidaturAntritt(direktkandidatur));
  }

  default long getAnzahlStimmenLautQuorumMinimal(Sitzberechnungseingabe<K> sitzberechnungseingabe, Wahldurchfuehrungsgebiet direktwahlgebiet) {
    return getErgebnisDatenQuorumWahlberechtigte(sitzberechnungseingabe).getAnzahlQuorumErreicht(direktwahlgebiet);
  }

  default ErgebnisDatenQuorum getErgebnisDatenQuorumWahlberechtigte(Sitzberechnungseingabe<K> sitzberechnungseingabe) {
    return sitzberechnungseingabe.getStimmergebnisDaten().getErgebnisDatenQuorumWahlberechtigte();
  }
}
