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

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Function;

import de.ivu.elect.business.person.entity.Personendaten;
import de.ivu.elect.jee.entity.Entity;
import de.ivu.elect.util.MapBuilder;

public abstract class AbstractAehnlichePersonenFinder<T extends Personendaten, W extends Entity> {

  protected AbstractAehnlichePersonenFinder() {
    super();
  }

  public List<T> findeAehnlichePersonen(Collection< ? extends T> personen) {
    List<T> result = new ArrayList<>();

    Map<W, List<T>> personenPerWahlOderWahltermin = collectPersonenPerWahlOderWahltermin(personen);

    for (Entry<W, List<T>> entry : personenPerWahlOderWahltermin.entrySet()) {
      result.addAll(findeAehnlichePersonen(entry.getKey(), entry.getValue()));
    }

    return result;
  }

  private Map<W, List<T>> collectPersonenPerWahlOderWahltermin(Collection< ? extends T> personen) {
    return MapBuilder.newMapMultipleEntriesFrom(personen, getPersonNachWahlOderWahlterminFunction());
  }

  protected abstract List< ? extends T> findeAehnlichePersonen(W wahlOderWahltermin, List<T> personen);

  protected abstract Function<T, W> getPersonNachWahlOderWahlterminFunction();
}
