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

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import de.ivu.elect.business.person.entity.AbstractPersonendaten;
import de.ivu.elect.business.staat.entity.Staat;


import static java.util.Arrays.asList;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.split;

public class StaatByStaatsangehoerigkeitenSortOrderComparator implements Comparator<Staat> {

  private final List<String> sortOrder;

  public StaatByStaatsangehoerigkeitenSortOrderComparator(AbstractPersonendaten personendaten) {
    this.sortOrder = extractSortOrderOrDefault(personendaten);
  }

  private static List<String> extractSortOrderOrDefault(AbstractPersonendaten personendaten) {
    List<String> result = splitStaatsangehoerigkeitenSortOrder(personendaten);

    for (Iterator<String> iter = result.iterator(); iter.hasNext();) {
      if (isBlank(iter.next())) {
        iter.remove();
      }
    }

    return result;
  }

  private static List<String> splitStaatsangehoerigkeitenSortOrder(AbstractPersonendaten personendaten) {
    String sortOrder = personendaten.getStaatsangehoerigkeitenSortOrder();

    if (isBlank(sortOrder)) {
      sortOrder = "";
    }

    return new ArrayList<>(asList(split(sortOrder, AbstractPersonendaten.ATTRIBUTE_AS_LIST_SEPARATOR)));
  }

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

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

      return -1;
    }

    return 1;
  }

  private int compare(String one, String another) {
    if (sortOrder.contains(one) && sortOrder.contains(another)) {
      return Integer.valueOf(sortOrder.indexOf(one)).compareTo(sortOrder.indexOf(another));
    }

    if (sortOrder.contains(one)) {
      return -1;
    }

    if (sortOrder.contains(another)) {
      return 1;
    }

    return 0;
  }
}
