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

import java.util.Map;
import java.util.function.Predicate;

import javax.annotation.Nullable;

import de.ivu.elect.business.gebietsbaum.entity.Gebiet;

public abstract class AbstractAWerteAktualisierer<G extends Gebiet> {

  @Nullable
  protected Long getAWertKumuliert(G wahldurchfuehrungsgebiet, Map<G, Long> aWertNachErfassungsgebietMap) {
    return getAWertKumuliert(wahldurchfuehrungsgebiet, aWertNachErfassungsgebietMap, this::isErfassungsgebiet);
  }

  public static <G extends Gebiet> Long getAWertKumuliert(G wahldurchfuehrungsgebiet, Map<G, Long> aWertNachErfassungsgebietMap,
                                                          Predicate<G> erfassungsgebiet) {

    var result = aWertNachErfassungsgebietMap.get(wahldurchfuehrungsgebiet);

    if (result == null) {
      for (var entry : aWertNachErfassungsgebietMap.entrySet()) {
        var key = entry.getKey();
        var value = entry.getValue();
        if (erfassungsgebiet.test(key) && key.isInGebietshierarchieUntergeordnetesGebietVon(wahldurchfuehrungsgebiet) && value != null) {
          if (result == null) {
            result = value;
          } else {
            result += value;
          }
        }
      }
    }

    return result;
  }

  protected abstract boolean isErfassungsgebiet(G gebiet);

  public abstract boolean isAWerteAktualisieren(G gebiet);

  public abstract void aWerteZuruecksetzen(G gebiet);

}
