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

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.ejb.Stateless;

import de.ivu.elect.business.gebietsbaum.control.GebietByBreadthFirstComparator;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Wahltermin;

@Stateless
public class GebietSearch extends AbstractGebietSearch {

  public GebietSearch() {
    super();
  }

  @Override
  protected List<Gebiet> querySearchResult(GebietSearchParameters searchParameters) {
    List<Gebiet> result = new ArrayList<>();

    if (searchParameters.getUebergeordnetesGebiet() == null) {
      return Collections.emptyList(); // Kein Gebiet  => kein Ergebnis
    }

    if (searchParameters.hasWahl()) {
      result.addAll(getSearchResultByWahl(searchParameters.getWahl(), searchParameters));
    } else if (searchParameters.hasWahltermin()) {
      result.addAll(getSearchResultByWahltermin(searchParameters.getWahltermin(), searchParameters));
    }

    result.sort(new GebietByBreadthFirstComparator());

    addOberstesGebiet(searchParameters, result);

    return result;
  }

  protected void addOberstesGebiet(GebietSearchParameters searchParameters, List<Gebiet> result) {
    // NOTE, dass auf jeder Ebene im Gebietsbaum auch das aktuell ausgewählte Gebiet zur Bearbeitung auswählbar sein
    if (searchParameters.hasUebergeordnetesGebiet()) {
      result.add(0, attach(searchParameters.getUebergeordnetesGebiet()));
    }
  }

  private List<Gebiet> getSearchResultByWahltermin(Wahltermin wahltermin, GebietSearchParameters searchParameters) {
    if (searchParameters.hasUebergeordnetesGebiet()) {
      return dao.findByWahlterminAndUebergeordnetemGebiet(wahltermin, searchParameters.getUebergeordnetesGebiet());
    }

    return dao.findByWahltermin(wahltermin);
  }

  protected List<Gebiet> getSearchResultByWahl(Wahl wahl, GebietSearchParameters searchParameters) {
    if (searchParameters.hasUebergeordnetesGebiet()) {
      return dao.findByWahlAndUebergeordnetemGebiet(wahl, searchParameters.getUebergeordnetesGebiet());
    }

    return dao.findByWahl(wahl);
  }

  protected Gebiet attach(Gebiet gebiet) {
    return dao.attach(gebiet);
  }
}
