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

import java.io.Serializable;
import java.util.List;

import javax.annotation.Nullable;

import de.ivu.elect.business.personenregister.entity.PersonenregisterEinwohnerstatus;
import de.ivu.elect.business.personenregister.entity.PersonenregisterEinwohnerstatusProperty;
import de.ivu.elect.business.wahl.entity.Wahltermin;

public abstract class AbstractPersonenregisterSearchParameters implements Serializable {

  private static final long serialVersionUID = 1L;

  public static final PersonenregisterEinwohnerstatus DEFAULT_PERSONENREGISTER_EINWOHNERSTATUS = PersonenregisterEinwohnerstatus.AKTIV;

  /**** !!!!!!!!!!!!! ***********/
  /* ELECT-11217 neue Suchparameter in getParameterValues() aufnehmen!! ***/
  /**** !!!!!!!!!!!!! ***********/

  @Nullable
  private Wahltermin wahltermin;

  private PersonenregisterEinwohnerstatus einwohnerstatus;

  private transient PersonenregisterEinwohnerstatusProperty einwohnerstatusProperty;

  private boolean preventCacheLookup = false; // Anfrage ausführen, kein Cache benutzen

  protected AbstractPersonenregisterSearchParameters(@Nullable Wahltermin wahltermin, PersonenregisterEinwohnerstatus einwohnerstatus) {
    super();

    // NOTE, dass die Setter explizit aufgerufen werden, um ggf. deren Spezialbehandlungen, cf. MesoByPersonendatenSearchParameters, durchzuführen!!!
    setWahltermin(wahltermin);

    setEinwohnerstatus(einwohnerstatus);
  }

  public boolean isPreventCacheLookup() {
    return preventCacheLookup;
  }

  public void setPreventCacheLookup(boolean preventCacheLookup) {
    this.preventCacheLookup = preventCacheLookup;
  }

  public boolean hasWahltermin() {
    return getWahltermin() != null;
  }

  @Nullable
  public Wahltermin getWahltermin() {
    return wahltermin;
  }

  public void setWahltermin(@Nullable Wahltermin wahltermin) {
    this.wahltermin = wahltermin;
  }

  public boolean hasEinwohnerstatus() {
    return getEinwohnerstatus() != null && !getEinwohnerstatus().isUnbekannt();
  }

  public PersonenregisterEinwohnerstatus getEinwohnerstatus() {
    return einwohnerstatus;
  }

  public void setEinwohnerstatus(PersonenregisterEinwohnerstatus einwohnerstatus) {
    this.einwohnerstatus = einwohnerstatus;
  }

  public PersonenregisterEinwohnerstatusProperty getEinwohnerstatusProperty() {
    if (einwohnerstatusProperty == null) {
      einwohnerstatusProperty = createEinwohnerstatusProperty();
    }

    return einwohnerstatusProperty;
  }

  protected PersonenregisterEinwohnerstatusProperty createEinwohnerstatusProperty() {
    return new PersonenregisterEinwohnerstatusProperty(this);
  }

  public String getCacheKey() {
    StringBuilder sb = new StringBuilder();
    sb.append(wahltermin);
    sb.append("_");
    sb.append(einwohnerstatus);
    sb.append("_");
    for (Object parameterValue : getParameterValues()) {
      sb.append(parameterValue);
      sb.append("_");
    }
    return sb.toString();
  }

  protected abstract List<Object> getParameterValues();

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    AbstractPersonenregisterSearchParameters that = (AbstractPersonenregisterSearchParameters) o;

    if (wahltermin != null ? !wahltermin.equals(that.wahltermin) : that.wahltermin != null) return false;
    return einwohnerstatus == that.einwohnerstatus;
  }

  @Override
  public int hashCode() {
    int result = wahltermin != null ? wahltermin.hashCode() : 0;
    result = 31 * result + (einwohnerstatus != null ? einwohnerstatus.hashCode() : 0);
    return result;
  }
}
