
package de.ivu.elect.was.exchange.ergebnis.zusammenstellung;

import static java.util.Collections.unmodifiableList;
import static java.util.stream.Collectors.toUnmodifiableSet;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import de.ivu.elect.business.gebietsbaum.boundary.WahlverwaltungGebietInformation;
import de.ivu.elect.business.wahl.entity.WahlartErgebnisart;

/**
 * Zum einfacheren Verständnis werden die Begriffe "Dokument", "Tabelle", "Zeile", etc. verwendet. Die Objekte selbst sind allerdings unabhängig von der konkreten Darstellung (als Tabelle, Liste,
 * etc.) und werden erst später "in Form" gebracht. Es gilt...
 *
 * <ul>
 * <li>ein Dokument bezieht sich auf ein Wahl</li>
 * <li>ein Dokument enthält Tabellen</li>
 * <li>eine Tabelle bezieht sich auf ein Stimmzettelgebiet</li>
 * <li>eine Tabelle hat Zeilen</li>
 * <li>eine Zeile bezieht sich auf ein Erfassungsgebiet</li>
 * </ul>
 */
public class ErgebnisZusammenstellungDokument {

  private final String wahlName;

  private final Date wahlDatum;

  private final WahlartErgebnisart ergebnisart;

  private final List<ErgebnisZusammenstellungTabelle> tabellen;

  public ErgebnisZusammenstellungDokument(ErgebnisZusammenstellungDokument template, List<ErgebnisZusammenstellungTabelle> tabellen) {
    this(template.getWahlName(), template.getWahlDatum(), template.getErgebnisart(), tabellen);
  }

  public ErgebnisZusammenstellungDokument(String wahlName, Date wahlDatum, WahlartErgebnisart ergebnisart, List<ErgebnisZusammenstellungTabelle> tabellen) {
    super();

    this.wahlName = wahlName;
    this.wahlDatum = wahlDatum;

    this.ergebnisart = ergebnisart;

    this.tabellen = unmodifiableList(tabellen);
  }

  public String getWahlName() {
    return wahlName;
  }

  public Date getWahlDatum() {
    return wahlDatum;
  }

  public boolean getErgebnisartVorlaeufig() {
    return getErgebnisart().isVorlaeufig();
  }

  public boolean getErgebnisartEndgueltig() {
    return getErgebnisart().isEndgueltig();
  }

  public WahlartErgebnisart getErgebnisart() {
    return ergebnisart;
  }

  public Collection<WahlverwaltungGebietInformation> getStimmzettelgebiete() {
    return getTabellen().stream().map(ErgebnisZusammenstellungTabelle::getStimmzettelgebiet).collect(toUnmodifiableSet());
  }

  public Optional<ErgebnisZusammenstellungTabelle> getTabelle(WahlverwaltungGebietInformation stimmzettelgebiet) {
    return getTabellen().stream().filter(tabelle -> Objects.equals(tabelle.getStimmzettelgebiet(), stimmzettelgebiet)).findFirst();
  }

  private List<ErgebnisZusammenstellungTabelle> getTabellen() {
    return tabellen;
  }
}
