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

import java.util.Objects;

import javax.annotation.Nullable;
import javax.inject.Inject;

import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import de.ivu.elect.business.wahlrechtspruefung.boundary.PruefkriteriumDAO;
import de.ivu.elect.business.wahlrechtspruefung.entity.Pruefkriterium;
import de.ivu.elect.business.wahlrechtspruefung.entity.PruefkriteriumDaoContainer;
import de.ivu.elect.business.wahlrechtspruefung.entity.WahlrechtspruefStatus;
import de.ivu.elect.business.wahlrechtspruefung.entity.Wahlrechtspruefung;
import de.ivu.elect.business.wahlvorschlag.entity.Wahlvorschlag;

public class WahlrechtspruefungCreate extends AbstractWahlrechtspruefungCreate {

  @Inject
  private transient PruefkriteriumDAO pruefkriteriumDAO;

  @Inject
  private transient PruefkriteriumDaoContainer pruefkriteriumDaoContainer;

  public WahlrechtspruefungCreate() {
    super();
  }

  public void save(Pruefkriterium pruefkriterium, Object entitaetZuPruefen, @Nullable Kandidatur kandidatur) {
    Wahlrechtspruefung wahlrechtspruefung = new Wahlrechtspruefung();
    wahlrechtspruefung.setPruefkriterium(pruefkriterium);
    wahlrechtspruefung.setWahlrechtspruefStatus(getWahlrechtspruefStatusInitial());
    wahlrechtspruefung.setKandidatur(kandidatur);

    pruefkriterium.getPruefkriteriumBezug().setzeZuPruefendeEntitaet(wahlrechtspruefung, entitaetZuPruefen, pruefkriteriumDaoContainer);

    save(wahlrechtspruefung);
  }

  protected WahlrechtspruefStatus getWahlrechtspruefStatusInitial() {
    return WahlrechtspruefStatus.UNGEPRUEFT;
  }

  @Override
  public void save(Wahlrechtspruefung wahlrechtspruefung) {
    // ELECT-10913, Wahlrechtsprüfungen nur einmalig (beim Import oder dem Anlegen eines Wahlvorschlages/einer Kandidatur) anlegen...
    if (!existsWahlrechtspruefung(attach(wahlrechtspruefung.getPruefkriterium()), attach(wahlrechtspruefung.getWahlvorschlag()), wahlrechtspruefung.getKandidatur())) {
      super.save(wahlrechtspruefung);
    }
  }

  private boolean existsWahlrechtspruefung(Pruefkriterium pruefkriterium, Wahlvorschlag wahlvorschlag, Kandidatur kandidatur) {
    if (wahlvorschlag != null) {
      return dao.findByWahlvorschlag(wahlvorschlag).stream()
          .anyMatch(wahlrechtspruefung -> Objects.equals(wahlrechtspruefung.getPruefkriterium(), pruefkriterium) && Objects.equals(wahlrechtspruefung.getKandidatur(), kandidatur));
    }

    return false;
  }

  private Pruefkriterium attach(Pruefkriterium pruefkriterium) {
    return pruefkriteriumDAO.attach(pruefkriterium);
  }

  private Wahlvorschlag attach(Wahlvorschlag wahlvorschlag) {
    return pruefkriteriumDaoContainer.getWahlvorschlagDAO().attach(wahlvorschlag);
  }
}
