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

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.ejb.Stateless;
import javax.inject.Inject;

import de.ivu.elect.business.datei.entity.DateiExport;
import de.ivu.elect.business.datei.entity.FileType;
import de.ivu.elect.business.dokumente.boundary.AbstractDokumentGenerator;
import de.ivu.elect.business.dokumente.control.ProgressMonitor;
import de.ivu.elect.business.dokumente.entity.DokumentVorlage;
import de.ivu.elect.business.dokumente.entity.DokumentVorlageArt;
import de.ivu.elect.business.ergebnis.control.ErgebnisDaten;
import de.ivu.elect.business.ergebnis.control.ErgebnisDatenCreator;
import de.ivu.elect.business.ergebnis.entity.Ergebnis;
import de.ivu.elect.business.gebietsbaum.boundary.GebietDAO;
import de.ivu.elect.business.gebietsbaum.boundary.GebietsartCreator;
import de.ivu.elect.business.gebietsbaum.boundary.GebietsartTemplate;
import de.ivu.elect.business.gebietsbaum.control.GebietByBreadthFirstComparator;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Wahltermin;

@Stateless
public class GesamtErgebnisDokumentGenerator extends AbstractDokumentGenerator<Ergebnis, GesamtErgebnisDokumentContext> {

  @Inject
  private transient GebietDAO gebietDAO;

  @Inject
  private transient ErgebnisDAO ergebnisDAO;

  @Inject
  private transient ErgebnisDatenCreator ergebnisDatenCreator;

  @Inject
  private transient GebietsartCreator gebietsartCreator;

  public GesamtErgebnisDokumentGenerator() {
    super();
  }

  @Override
  public DokumentVorlageArt getDokumentVorlageArt() {
    return DokumentVorlageArt.GESAMT_ERGEBNIS;
  }

  @Override
  protected Ergebnis attach(Ergebnis template, GesamtErgebnisDokumentContext context) {
    Ergebnis ergebnis = ergebnisDAO.attach(template);
    ErgebnisDaten ergebnisDaten = ergebnisDatenCreator.createErgebnisDatenExporte(ergebnis);

    List<Wahldurchfuehrungsgebiet> gebiete = attachGebiete(context, ergebnisDaten.getGebiete());

    Collection<GebietsartTemplate> gebieteMitDetailsGebietsarten = context.getGebieteMitDetailsGebietsarten();
    List<Wahldurchfuehrungsgebiet> gebieteMitDetails = new ArrayList<>();

    if (!gebiete.isEmpty() && !gebieteMitDetailsGebietsarten.isEmpty()) {
      Collection< ? extends GebietsartTemplate> gebietsartenInSystem = gebietsartCreator.getGebietsartTemplates(ergebnis.getMandant());

      for (Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet : gebiete) {
        if (gebieteMitDetailsGebietsarten.contains(wahldurchfuehrungsgebiet.getGebietsart().getCustomGebietsartTemplate(gebietsartenInSystem))) {
          gebieteMitDetails.add(wahldurchfuehrungsgebiet);
        }
      }

      gebieteMitDetails.sort(new GebietByBreadthFirstComparator());
    }

    context.setErgebnisDaten(ergebnisDaten);

    context.setGebiete(gebiete);
    context.setGebieteMitDetails(gebieteMitDetails);

    return ergebnis;
  }

  public List<Wahldurchfuehrungsgebiet> attachGebiete(GesamtErgebnisDokumentContext context, List<Wahldurchfuehrungsgebiet> gebiete) {
    List<Wahldurchfuehrungsgebiet> result = new ArrayList<>(context.collectGebieteExportierbar(gebietDAO, gebiete));
    result.sort(new GebietByBreadthFirstComparator());

    return result;
  }

  @Override
  protected void postGeneriereDokument(DateiExport dateiExport, List<Ergebnis> ergebnisse, DokumentVorlage dokumentVorlage, FileType zieldateiTyp, Wahl wahl, Wahltermin wahltermin,
      GesamtErgebnisDokumentContext context, ProgressMonitor monitor) {
    super.postGeneriereDokument(dateiExport, ergebnisse, dokumentVorlage, zieldateiTyp, wahl, wahltermin, context, monitor);

    // Aufräumen für Garbage Collection...
    context.removeErgebnisDaten();

    context.removeGebiete();
    context.removeGebieteMitDetails();
  }
}
