
package de.ivu.elect.jee.faces;

import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import static org.apache.commons.lang3.StringUtils.isBlank;

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

import javax.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity;

import de.ivu.elect.util.CaseAndDiacriticIgnoringComparator;

public class FacesMessageComparable implements Comparable<FacesMessage>, Serializable {

  private static final long serialVersionUID = 1L;

  private static final Comparator<String> DEFAULT_STRING_COMPARATOR = CaseAndDiacriticIgnoringComparator.DEFAULT_INSTANCE;

  private final FacesMessage facesMessage;

  public FacesMessageComparable(FacesMessage facesMessage) {
    super();

    this.facesMessage = facesMessage;
  }

  public int compareTo(FacesMessageComparable another) {
    return compareTo(another.facesMessage);
  }

  @Override
  public int compareTo(FacesMessage another) {
    if (nonNull(another)) {
      int comparedBySeverity = compare(facesMessage.getSeverity(), another.getSeverity());

      if (comparedBySeverity == 0) {
        int comparedBySummary = compare(facesMessage.getSummary(), another.getSummary());

        if (comparedBySummary == 0) {
          return DEFAULT_STRING_COMPARATOR.compare(facesMessage.getDetail(), another.getDetail());
        }

        return comparedBySummary;
      }

      return comparedBySeverity;
    }

    return -1;
  }

  private int compare(Severity one, Severity another) {
    if (nonNull(one) && nonNull(another)) {
      return one.compareTo(another);
    }

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

      return -1;
    }

    return 1;
  }

  private int compare(String one, String another) {
    return DEFAULT_STRING_COMPARATOR.compare(one, another);
  }

  @Override
  public int hashCode() {
    final int prime = 31;

    int result = 1;
    result = prime * result + (isBlank(facesMessage.getDetail()) ? 0 : facesMessage.getDetail().hashCode());
    result = prime * result + (isNull(facesMessage.getSeverity()) ? 0 : facesMessage.getSeverity().hashCode());
    result = prime * result + (isBlank(facesMessage.getSummary()) ? 0 : facesMessage.getSummary().hashCode());

    return result;
  }

  @Override
  public boolean equals(Object object) {
    if (this == object) {
      return true;
    }

    if (object instanceof FacesMessageComparable) {
      return this.compareTo((FacesMessageComparable) object) == 0;
    }

    if (object instanceof FacesMessage) {
      return this.compareTo((FacesMessage) object) == 0;
    }

    return false;
  }
}
