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

import java.util.Collection;
import java.util.Map;

import de.ivu.elect.business.person.control.AbstractPersonenVerknuepfungAktualisierer;
import de.ivu.elect.business.person.entity.PersonenVerknuepfung;
import de.ivu.elect.business.person.entity.Personendaten;
import de.ivu.elect.business.person.entity.VerknuepfungsArt;
import de.ivu.elect.business.person.entity.VerknuepfungsGrundlage;
import de.ivu.elect.business.person.entity.VerknuepfungsStatus;
import de.ivu.elect.business.personenpruefung.control.AbstractPersonenPruefSchritt;
import de.ivu.elect.business.personenpruefung.entity.PersonenKonflikt;
import de.ivu.elect.business.personenpruefung.entity.PersonenKonfliktArt;
import de.ivu.elect.business.personenpruefung.entity.PersonenKonfliktStatus;

/*
 * NOTE: EIN Konflikt des AbstractPersonenDublettenPruefSchritt kann sich auf MEHRERE Dubletten beziehen!
 *
 * Ein vorhandener Dubletten-Konflikt zeigt daher nur das Vorhandensein ungelöster VERKNÜPFUNGEN an und sollte daher auch NICHT IRRELEVANT
 * gesetzt werden (sonst würden alle möglichen neuen Verknüpfungen ignoriert werden)!
 */
public abstract class AbstractPersonenDublettenPruefSchritt extends AbstractPersonenPruefSchritt {

  public AbstractPersonenDublettenPruefSchritt() {
    super();
  }

  @Override
  public boolean isInstantPersonenPruefSchritt() {
    return false;
  }

  @Override
  public PersonenKonfliktArt getPersonenKonfliktArt() {
    return PersonenKonfliktArt.POTENTIELLE_DUBLETTE;
  }

  @Override
  public PersonenKonfliktStatus getPersonenKonfliktStatus() {
    return PersonenKonfliktStatus.MANUELL_ZU_PRUEFEN;
  }

  @Override
  public Collection<Class< ? extends Personendaten>> getRelevantPersonendatenClasses() {
    return getPersonenVerknuepfungAktualisierer().getZuPruefendePersonendatenClasses();
  }

  @Override
  public Map<Personendaten, PersonenKonflikt> pruefe(Collection<Personendaten> personen) {
    getPersonenVerknuepfungAktualisierer().ergaenzeFehlendeVerknuepfungen(personen);

    return super.pruefe(personen);
  }

  protected abstract AbstractPersonenVerknuepfungAktualisierer<Personendaten> getPersonenVerknuepfungAktualisierer();

  @Override
  public boolean isPotentiellNichtGeeignet(Personendaten personendaten) {
    for (PersonenVerknuepfung personenVerknuepfung : personendaten.getPersonenVerknuepfungen()) {
      if (!isZulaessigePersonenVerknuepfung(personenVerknuepfung) && !isZulaessigeDublette(personenVerknuepfung)) {
        return true;
      }
    }

    return false;
  }

  private boolean isZulaessigePersonenVerknuepfung(PersonenVerknuepfung personenVerknuepfung) {
    return !getVerknuepfungsArt().equals(personenVerknuepfung.getVerknuepfungsArt()) || VerknuepfungsGrundlage.MANUELL.equals(personenVerknuepfung.getVerknuepfungsGrundlage())
        || VerknuepfungsStatus.VERSCHIEDEN.equals(personenVerknuepfung.getVerknuepfungsStatus());
  }

  private boolean isZulaessigeDublette(PersonenVerknuepfung personenVerknuepfung) {
    return getPersonenDublettenZulaessigkeitPruefer().isZulaessigeDublette(personenVerknuepfung.getPerson1(), personenVerknuepfung.getPerson2());
  }

  protected abstract AbstractPersonenDublettenZulaessigkeitPruefer getPersonenDublettenZulaessigkeitPruefer();

  protected VerknuepfungsArt getVerknuepfungsArt() {
    return getPersonenVerknuepfungAktualisierer().getVerknuepfungsArt();
  }
}
