
package de.ivu.elect.business.ergebnis.control;

import static java.util.Arrays.asList;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import de.ivu.elect.business.ergebnis.entity.Stimmenart;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.gruppe.entity.SystemGruppe;
import de.ivu.elect.business.internet.control.GebietUndStimmabgabeart;

// ELECTKOM-2783
public class ErgebnisDatenWahlbriefe extends AbstractErgebnisDaten {

  public static final SystemGruppe SYSTEM_GRUPPE_WAHLBRIEFE = SystemGruppe.WAEHLER;

  public static final Stimmenart STIMMENART_ZURUECKGEWIESEN_GESAMT = Stimmenart.GESAMT_ABWEICHEND_ZUWENIG;

  private static final List<Stimmenart> TARGET_STIMMENARTEN_WAHLBRIEFE = asList(STIMMENART_ZURUECKGEWIESEN_GESAMT);

  private final StimmenKumulierer stimmenKumulierer;

  private final StimmenPool stimmenPool;

  public ErgebnisDatenWahlbriefe(StimmergebnisDaten stimmergebnisDaten) {
    super(stimmergebnisDaten::getUntergeordneteGebiete, stimmergebnisDaten::getErfassteGebiete);

    this.stimmenKumulierer = stimmergebnisDaten.getStimmenKumulierer();

    this.stimmenPool = stimmergebnisDaten.getStimmen();
  }

  public long getSummeWahlbriefeZurueckgewiesenGesamt(GebietUndStimmabgabeart gebietUndStimmabgabeart) {
    return getSummeWahlbriefe(gebietUndStimmabgabeart, STIMMENART_ZURUECKGEWIESEN_GESAMT);
  }

  private long getSummeWahlbriefe(GebietUndStimmabgabeart gebietUndStimmabgabeart, Stimmenart stimmenart) {
    return notNull(getSummeWahlbriefe(gebietUndStimmabgabeart).get(stimmenart));
  }
 
  private Map<Stimmenart, Long> getSummeWahlbriefe(GebietUndStimmabgabeart gebietUndStimmabgabeart) {
    return bestimmeStimmenOderSummiereAufUntergebieten(gebietUndStimmabgabeart, cacheWahlbriefe, bestimmeWahlbriefe);
  }

  private final Map<GebietUndStimmabgabeart, Map<Stimmenart, Long>> cacheWahlbriefe = new HashMap<>();

  private final BestimmeStimmen<Stimmenart, GebietUndStimmabgabeart> bestimmeWahlbriefe = new BestimmeStimmen<>() {

    @Override
    public Long ermittleStimmen(Stimmenart stimmenart, Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
      return stimmenKumulierer.bestimmeSummeSystemGruppenStimmenAufGebiet(stimmenPool, wahldurchfuehrungsgebiet, SYSTEM_GRUPPE_WAHLBRIEFE, stimmenart);
    }

    @Override
    public Map<Stimmenart, Long> getErgebnisUntergebiet(GebietUndStimmabgabeart gebietUndStimmabgabeart) {
      return getSummeWahlbriefe(gebietUndStimmabgabeart);
    }

    @Override
    public List<Stimmenart> getTargetAufGebiet(GebietUndStimmabgabeart gebietUndStimmabgabeart) {
      return TARGET_STIMMENARTEN_WAHLBRIEFE;
    }
  };
}
