package de.ivu.elect.presentation.wahlrechtspruefung;

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

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;

import de.ivu.elect.jee.entity.EagerLoadingCollector;
import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import de.ivu.elect.business.wahlrechtspruefung.boundary.WahlrechtspruefungSearch;
import de.ivu.elect.business.wahlrechtspruefung.boundary.WahlrechtspruefungSearchParameters;
import de.ivu.elect.business.wahlrechtspruefung.entity.WahlrechtspruefStatus;
import de.ivu.elect.business.wahlrechtspruefung.entity.Wahlrechtspruefung;
import de.ivu.elect.business.wahlrechtspruefung.entity.WahlrechtspruefungObjekt;
import de.ivu.elect.business.wahlvorschlag.entity.Wahlvorschlag;

@RequestScoped
public class WahlrechtspruefungRequestCache implements Serializable {

  @Inject
  WahlrechtspruefungSearch wahlrechtspruefungSearch;

  Map<WahlrechtspruefungObjekt, List<Wahlrechtspruefung>> wahlrechtspruegfungenProObjekt = new HashMap<>();

  public List<Wahlrechtspruefung> getWahlrechtspruefungenFuerKandidatur(Kandidatur kandidatur) {
    return getWahlrechtspruefungenFuer(kandidatur.getWahlvorschlag(), kandidatur);
  }

  public List<Wahlrechtspruefung> getWahlrechtspruefungenFuerWahlvorschlag(Wahlvorschlag wahlvorschlag) {
    return getWahlrechtspruefungenFuer(wahlvorschlag, null);
  }

  private List<Wahlrechtspruefung> getWahlrechtspruefungenFuer(Wahlvorschlag wahlvorschlag, Kandidatur kandidatur) {
    WahlrechtspruefungObjekt wahlrechtspruefungObjekt = new WahlrechtspruefungObjekt(wahlvorschlag, kandidatur);
    if (!wahlrechtspruegfungenProObjekt.containsKey(wahlrechtspruefungObjekt)) {

      WahlrechtspruefungSearchParameters searchParameter = new WahlrechtspruefungSearchParameters();
      searchParameter.apply(wahlrechtspruefungObjekt);
      wahlrechtspruegfungenProObjekt.put(wahlrechtspruefungObjekt, wahlrechtspruefungSearch.getSearchResult(searchParameter, EagerLoadingCollector.<Wahlrechtspruefung>create()));
    }

    return wahlrechtspruegfungenProObjekt.get(wahlrechtspruefungObjekt);

  }

  public Long getAnzahlPruefungenMitStatus(Wahlvorschlag wahlvorschlag, WahlrechtspruefStatus wahlrechtspruefStatus) {
    return getAnzahlPruefungenMitStatus(wahlvorschlag, null, wahlrechtspruefStatus);
  }

  public Long getAnzahlPruefungenMitStatus(Kandidatur kandidatur, WahlrechtspruefStatus wahlrechtspruefStatus) {
    return getAnzahlPruefungenMitStatus(kandidatur.getWahlvorschlag(), kandidatur, wahlrechtspruefStatus);
  }

  private Long getAnzahlPruefungenMitStatus(Wahlvorschlag wahlvorschlag, Kandidatur kandidatur, WahlrechtspruefStatus wahlrechtspruefStatus) {
    Long result = 0L;

    for (Wahlrechtspruefung wahlrechtspruefung : getWahlrechtspruefungenFuer(wahlvorschlag, kandidatur)) {
      if (wahlrechtspruefStatus.equals(wahlrechtspruefung.getWahlrechtspruefStatus())) {
        result += 1;
      }
    }

    return result;
  }
}
