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

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

import de.ivu.elect.business.ergebnis.entity.ErgebnisLogEintrag;
import de.ivu.elect.business.ergebnis.entity.Gewaehlt;
import de.ivu.elect.business.ergebnis.entity.Sitze;
import de.ivu.elect.business.ergebniskonflikt.entity.ErgebnisKonflikt;
import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebietTK;
import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import de.ivu.elect.business.sitzberechnung.entity.Sitzberechnungsergebnis;

public class SitzberechnungsergebnisVergleicher {

  private int count = 0;
  private final Map<Kandidatur, GewaehlteVergleicher> kandidatur2GewaehlteVergleicher = new HashMap<>();
  private final Map<GruppeImGebietTK, SitzeVergleicher> gruppeImGebiet2SitzeVergleicher = new HashMap<>();

  public void add(Sitzberechnungsergebnis sitzberechnungsergebnis) {
    count++;
    for (Gewaehlt gewaehlt : sitzberechnungsergebnis.getGewaehlte()) {
      getVergleicher(gewaehlt.getKandidatur()).add(gewaehlt);
    }
    for (Sitze sitze : sitzberechnungsergebnis.getSitze()) {
      getVergleicher(sitze.getGruppeImGebietTK()).add(sitze);
    }
  }

  private GewaehlteVergleicher getVergleicher(Kandidatur kandidatur) {
    GewaehlteVergleicher result = kandidatur2GewaehlteVergleicher.get(kandidatur);
    if (result == null) {
      result = new GewaehlteVergleicher();
      kandidatur2GewaehlteVergleicher.put(kandidatur, result);
    }
    return result;
  }

  private SitzeVergleicher getVergleicher(GruppeImGebietTK gruppeImGebiet) {
    SitzeVergleicher result = gruppeImGebiet2SitzeVergleicher.get(gruppeImGebiet);
    if (result == null) {
      result = new SitzeVergleicher();
      gruppeImGebiet2SitzeVergleicher.put(gruppeImGebiet, result);
    }
    return result;
  }

  public Sitzberechnungsergebnis getSitzberechnungsergebnis(List<ErgebnisKonflikt> konflikte,
      List<ErgebnisLogEintrag> ergebnisLogEintraege, VariantenStatistik variantenStatistik) {
    List<Sitze> sitze = mergeSitze();
    List<Gewaehlt> gewaehlte = mergeGewaehlte();
    return new Sitzberechnungsergebnis(sitze, gewaehlte, konflikte, ergebnisLogEintraege, variantenStatistik, null);
  }

  private List<Sitze> mergeSitze() {
    List<Sitze> result = new ArrayList<>();
    for (GruppeImGebietTK gruppeImGebiet : gruppeImGebiet2SitzeVergleicher.keySet()) {
      Sitze mergedValue = gruppeImGebiet2SitzeVergleicher.get(gruppeImGebiet).getMergedValue(count);
      if (mergedValue != null) {
        result.add(mergedValue);
      }
    }
    return result;
  }

  private List<Gewaehlt> mergeGewaehlte() {
    List<Gewaehlt> result = new ArrayList<>();
    for (Kandidatur kandidatur : kandidatur2GewaehlteVergleicher.keySet()) {
      Gewaehlt mergedValue = kandidatur2GewaehlteVergleicher.get(kandidatur).getMergedValue(count);
      if (mergedValue != null) {
        result.add(mergedValue);
      }
    }
    return result;
  }

}
