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

import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;

import java.io.Serializable;
import java.util.Collections;
import java.util.Comparator;

import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.gruppe.entity.GruppeConstants;

public class GruppeBySchluesselComparator implements Comparator<Gruppe>, Serializable {

  private static final long serialVersionUID = 1L;

  private static final String NUMERIC_SCHLUESSEL_LEFT_PADDED_FORMAT = "%" + GruppeConstants.SCHLUESSEL_MAX_LENGTH + "s";

  /**
   * A.k.a. "lexicographically"...
   */
  public static final Comparator<Gruppe> ASCENDING = new GruppeBySchluesselComparator();

  public static final Comparator<Gruppe> DESCENDING = Collections.reverseOrder(ASCENDING);

  public GruppeBySchluesselComparator() {
    super();
  }

  @Override
  public int compare(Gruppe one, Gruppe another) {
    if (one != null && another != null) {
      return compare(one.getSchluessel(), another.getSchluessel());
    }

    if (one == null) {
      if (another == null) {
        return 0;
      }

      return 1;
    }

    return -1;
  }

  public int compare(String one, String another) {
    if (isNotBlank(one) && isNotBlank(another)) {
      return normalizeSchluessel(one).compareToIgnoreCase(normalizeSchluessel(another));
    }

    if (isBlank(one)) {
      if (isBlank(another)) {
        return 0;
      }

      return 1;
    }

    return -1;
  }

  // NOTE ELECT-2204, dass diese Methode auch bei der Tabellen-Sortierung (nach String!) in der GUI aufgerufen wird!
  public static String normalizeSchluessel(String value) {
    if (isNumber(value)) {
      return formatLeftPadded(value);
    }

    return value;
  }

  private static boolean isNumber(String value) {
    return isNotBlank(value) && value.matches("[+-]?\\d+");
  }

  private static String formatLeftPadded(String value) {
    return String.format(NUMERIC_SCHLUESSEL_LEFT_PADDED_FORMAT, value).replaceAll("[\\s+]", "0");
  }
}
