
package de.ivu.elect.business.sitzberechnung.control.varianten;

import java.math.BigInteger;

/**
 * Hilfsklasse zum Variantenberechner, die die Anzahl der Sitzberechnungen u.ä. mitzählt, um am Ende eine entsprechende
 * Auswertung ermöglicht.
 * 
 *
 */
public class VariantenStatistik {

  private BigInteger anzahlDurchzufuehrendeSitzberechnungen = BigInteger.ZERO;
  private long anzahlDurchgefuehrteSitzberechnungen = 0;
  private long anzahlVariantenBerechnet = 0;
  private BigInteger anzahlVariantenErmittelt = BigInteger.ZERO;
  private long minimaleTiefeDesVariantenbaums = Long.MAX_VALUE;
  private long maximaleTiefeDesVariantenbaums = 0;

  void incrementAnzahlDurchzufuehrendeSitzberechnungenBy(long size) {
    incrementAnzahlDurchzufuehrendeSitzberechnungenBy(BigInteger.valueOf(size));
  }

  void incrementAnzahlDurchzufuehrendeSitzberechnungenBy(BigInteger size) {
    anzahlDurchzufuehrendeSitzberechnungen = anzahlDurchzufuehrendeSitzberechnungen.add(size);
  }

  void incrementAnzahlDurchgefuehrteSitzberechnungen() {
    anzahlDurchgefuehrteSitzberechnungen++;
  }

  void varianteGefunden(SitzberechnungseingabeUndErgebnis< ? > next) {
    anzahlVariantenBerechnet++;
    anzahlVariantenErmittelt = anzahlVariantenErmittelt.add(next.getZaehltFuerAnzahlVarianten());

    int tiefeImVariantenbaum = next.getTiefeImVariantenbaum();
    minimaleTiefeDesVariantenbaums = Math.min(minimaleTiefeDesVariantenbaums, tiefeImVariantenbaum);
    maximaleTiefeDesVariantenbaums = Math.max(maximaleTiefeDesVariantenbaums, tiefeImVariantenbaum);
  }

  public long getAnzahlDurchgefuehrteSitzberechnungen() {
    return anzahlDurchgefuehrteSitzberechnungen;
  }

  /**
   * @return die Anzahl an Sitzberechnungen, die (mindestens) durchzuführen wären, um alle erforderlichen Varianten zu
   *         berechnen. Jedoch maximal Long.MAX_VALUE. Wenn die Variantenberechnung abgebrochen wurde, ist der
   *         tatsächliche Wert möglicher Weise größer.
   */
  public long getAnzahlDurchzufuehrendeSitzberechnungen() {
    if (anzahlDurchzufuehrendeSitzberechnungen.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) >= 0) {
      return Long.MAX_VALUE;
    } else {
      return anzahlDurchzufuehrendeSitzberechnungen.longValue();
    }
  }

  public long getAnzahlVariantenBerechnet() {
    return anzahlVariantenBerechnet;
  }

  public BigInteger getAnzahlVariantenErmittelt() {
    return anzahlVariantenErmittelt;
  }

  /**
   * In unterschiedlichen Varianten können unterschiedlich viele ungelöste Konflitke auftreten, die noch durch den
   * Variantenberechner gelöst werden müssen. Dies ist der maximale Wert. Wenn die Variantenberechnung abgebrochen
   * wurde, ist der tatsächliche maximale Wert möglicher Weise größer.
   * 
   * @return maximale Anzahl Konflikte, die durch den Variantenberechner gelöst wurden, um zu einem Ergebnis zu gelangen
   */
  public long getMaximaleTiefeDesVariantenbaums() {
    return maximaleTiefeDesVariantenbaums;
  }

  /**
   * In unterschiedlichen Varianten können unterschiedlich viele ungelöste Konflitke auftreten, die noch durch den
   * Variantenberechner gelöst werden müssen. Dies ist der minimale Wert. Wenn die Variantenberechnung abgebrochen
   * wurde, ist der tatsächliche maximale Wert möglicher Weise größer. Wenn keine Variante zuende gerechnet wurde,
   * liefert diese Methode Long.MAX_VALUE.
   * 
   * @return minimale Anzahl Konflikte, die durch den Variantenberechner gelöst wurden, um zu einem Ergebnis zu gelangen
   */
  public long getMinimaleTiefeDesVariantenbaums() {
    return minimaleTiefeDesVariantenbaums;
  }

}
