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

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

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.WahlartSitzberechnungsalgorithmus;
import de.ivu.elect.business.wahl.entity.Wahldurchfuehrung;
import de.ivu.elect.jee.faces.Messages;

@RequestScoped
public class SitzberechnungsalgorithmusFinder implements Serializable {

  private static final Logger LOG = LoggerFactory.getLogger(SitzberechnungsalgorithmusFinder.class);

  private static final long serialVersionUID = 1L;

  @Inject
  private transient Instance<SitzberechnungsalgorithmusMarker> sitzberechnungsalgorithmen;

  @Inject
  private transient KeinSitzberechnungsalgorithmus keinSitzberechnungsalgorithmus;

  @Inject
  private transient Messages messages;

  public SitzberechnungsalgorithmusFinder() {
    super();
  }

  public List<Sitzberechnungsalgorithmus> getDefaultSitzberechnungsalgorithmusNameFuerWahl(Wahl wahl) {
    return getSitzberechnungsalgorithmen().stream() //
        .filter(a -> !a.getSitzberechnungsalgorithmusEnum().isDeprecated()) //
        .filter(a -> a.isDefaultFuerWahlart(wahl)) //
        .collect(toList());
  }

  public Sitzberechnungsalgorithmus getKeinSitzberechnungsalgorithmus() {
    return keinSitzberechnungsalgorithmus;
  }

  public Sitzberechnungsalgorithmus getSitzberechnungsalgorithmus(Wahldurchfuehrung wahldurchfuehrung) {
    return getSitzberechnungsalgorithmus(wahldurchfuehrung.getSitzberechnungsalgorithmus());

  }

  public Sitzberechnungsalgorithmus getSitzberechnungsalgorithmus(WahlartSitzberechnungsalgorithmus sitzberechnungsalgorithmusEnum) {
    if (sitzberechnungsalgorithmusEnum == null || sitzberechnungsalgorithmusEnum.isKeinSitzberechnungsalgorithmus()) {
      // ELECT-5896
      return getKeinSitzberechnungsalgorithmus();
    }

    for (Sitzberechnungsalgorithmus sitzberechnungsalgorithmus : getSitzberechnungsalgorithmen()) {
      if (sitzberechnungsalgorithmusEnum.equals(sitzberechnungsalgorithmus.getSitzberechnungsalgorithmusEnum())) {
        return sitzberechnungsalgorithmus;
      }
    }

    String vorhanden = getSitzberechnungsalgorithmen().stream().map(SitzberechnungsalgorithmusMarker::getSitzberechnungsalgorithmusEnum).map(messages::lokalisiere).collect(Collectors.joining(", "));

    LOG.warn(
        "Kein Sitzberechnungsalgorithmus mit dem Namen: '" + messages.lokalisiere(sitzberechnungsalgorithmusEnum) + "' (" + sitzberechnungsalgorithmusEnum + ")" + " gefunden, habe: " + vorhanden);
    return getKeinSitzberechnungsalgorithmus();
  }

  public List<Sitzberechnungsalgorithmus> getSitzberechnungsalgorithmen() {
    List<Sitzberechnungsalgorithmus> result = new ArrayList<>();
    for (SitzberechnungsalgorithmusMarker sitzberechnungsalgorithmusMarker : sitzberechnungsalgorithmen) {
      result.add((Sitzberechnungsalgorithmus) sitzberechnungsalgorithmusMarker);
    }
    return result;

  }

}
