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

import static java.util.Arrays.asList;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import javax.enterprise.inject.Specializes;

import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import de.ivu.elect.business.person.entity.Personendaten;
import de.ivu.elect.business.person.entity.VerknuepfungsArt;
import de.ivu.elect.business.personenpruefung.entity.PersonenKonfliktArt;
import de.ivu.elect.business.wahlausschuss.entity.Wahlausschussmitglied;

@Specializes
public class CorePersonenPruefungVorbereiter extends PersonenPruefungVorbereiter {

  private static final long serialVersionUID = 1L;

  /*
   * NOTE ELECT-2749, dass in Edit-Beans der Checker schon VOR dem Aufruf von super.save() erzeugt worden sein muss, diese Methode jedoch erst NACH dem Aufruf von super.save() aufgerufen werden darf!
   *
   * NOTE ELECT-2796, dass die Entität bei so einem Aufruf ATTACHED sein muss!
   */

  public CorePersonenPruefungVorbereiter() {
    super();
  }

  public void prepareWahlausschussmitgliedPruefung(Wahlausschussmitglied wahlausschussmitglied,
      WahlausschussmitgliedPruefungAttributeChangedChecker wahlausschussmitgliedPruefungAttributeChangedChecker) {
    Set<PersonenKonfliktArt> konfliktArten = new HashSet<>();

    if (wahlausschussmitgliedPruefungAttributeChangedChecker.isPersonenregisterAbgleichAttributeChanged()) {
      addKonfliktArtAndPreparePersonendatenForPersonenregisterAbgleichPruefSchritt(konfliktArten, wahlausschussmitglied);
    }

    if (wahlausschussmitgliedPruefungAttributeChangedChecker.isDublettenAttributeChanged()) {
      addKonfliktArtAndPreparePersonendatenForDublettenPruefSchritt(konfliktArten, wahlausschussmitglied);
    }

    if (wahlausschussmitgliedPruefungAttributeChangedChecker.isWahlrechtAttributeChanged()) {
      addKonfliktArtAndPreparePersonendatenForWahlrechtPruefSchritt(konfliktArten, wahlausschussmitglied);
    }

    deleteKonflikte(wahlausschussmitglied, konfliktArten);
  }

  public void prepareKandidaturPruefung(Kandidatur kandidatur, KandidaturPruefungAttributeChangedChecker kandidaturPruefungAttributeChangedChecker) {
    Set<PersonenKonfliktArt> konfliktArten = new HashSet<>();

    if (kandidaturPruefungAttributeChangedChecker.isPersonenregisterAbgleichAttributeChanged()) {
      addKonfliktArtAndPreparePersonendatenForPersonenregisterAbgleichPruefSchritt(konfliktArten, kandidatur);
    }

    if (kandidaturPruefungAttributeChangedChecker.isDublettenAttributeChanged()) {
      addKonfliktArtAndPreparePersonendatenForDublettenPruefSchritt(konfliktArten, kandidatur);
    }

    if (kandidaturPruefungAttributeChangedChecker.isMehrstaatigkeitAttributeChanged()) {
      addKonfliktArtAndPreparePersonendatenForMehrstaatigkeitPruefSchritt(konfliktArten, kandidatur);
    }

    if (kandidaturPruefungAttributeChangedChecker.isWahlrechtAttributeChanged()) {
      addKonfliktArtAndPreparePersonendatenForWahlrechtPruefSchritt(konfliktArten, kandidatur);
    }

    if (kandidaturPruefungAttributeChangedChecker.isWertelistenAbgleichAttributeChanged()) {
      addKonfliktArtAndPreparePersonendatenForWertelistenAbgleichPruefSchritt(konfliktArten, kandidatur);
    }

    deleteKonflikte(kandidatur, konfliktArten);
  }

  @Override
  protected Collection<VerknuepfungsArt> getDublettenVerknuepfungArten(Personendaten personendaten) {
    if (isZuPruefendePerson(personendaten)) {
      return asList(getDublettenVerknuepfungsArt());
    }

    return super.getDublettenVerknuepfungArten(personendaten);
  }

  protected VerknuepfungsArt getDublettenVerknuepfungsArt() {
    return VerknuepfungsArt.WAHLVORSCHLAG_DUBLETTE;
  }

  @Override
  protected boolean isZuPruefendePerson(Personendaten personendaten) {
    return super.isZuPruefendePerson(personendaten) && isZuPruefendePersonenArt(personendaten);
  }

  protected boolean isZuPruefendePersonenArt(Personendaten personendaten) {
    return isKandidatur(personendaten) || isWahlausschussmitglied(personendaten);
  }

  private boolean isKandidatur(Personendaten personendaten) {
    return personendaten.isInstanceOf(Kandidatur.class);
  }

  private boolean isWahlausschussmitglied(Personendaten personendaten) {
    return personendaten.isInstanceOf(Wahlausschussmitglied.class);
  }
}
