
package de.ivu.elect.util;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

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

public class ThrowableUtil {

  private ThrowableUtil() {
    super();
  }

  /**
   * Erzeugt einen String, der die Messages des Throwables <code>t</code> und aller seiner Gründe ( <code>t.getCause()</code>) enthält. Die Messages werden durch den <code>separator</code> getrennt.
   */
  public static String getMessagesAllerGruendeAlsString(Throwable t, String separator) {
    return join(getMessagesAllerGruende(t), separator);
  }

  /**
   * Gibt die Messages des Throwables <code>t</code> und aller seiner Gründe (<code>t.getCause()</code>) zurück.
   * <p/>
   * Die Ergebnis-Collection ist sortiert: <code>t.getLocalizedMessage()</code> kommt zuerst; die Message der Root Cause zuletzt.
   */
  public static List<String> getMessagesAllerGruende(Throwable t) {
    return getAlleGruende(t).stream().map(Throwable::getLocalizedMessage).collect(Collectors.toList());
  }

  /**
   * Gibt das Throwable <code>t</code> und alle seine Gründe (<code>t.getCause()</code>) zurück, bis zur Root Cause.
   * <p/>
   * Die Ergebnis-Collection ist sortiert: <code>t</code> kommt zuerst; die Root Cause zuletzt.
   */
  public static List<Throwable> getAlleGruende(Throwable t) {
    List<Throwable> result = new ArrayList<>();
    result.add(t);
    Throwable cause = t.getCause();
    if (cause != null) {
      result.addAll(getAlleGruende(cause));
    }
    return result;
  }

  /**
   * Gibt die Message des Root Cause zurück.
   */
  public static String getMessageDerUrsache(Throwable t) {
    List<String> messagesOrderedByRootCauseLast = new ArrayList<>(getMessagesAllerGruende(t));

    if (!messagesOrderedByRootCauseLast.isEmpty()) {
      for (int i = messagesOrderedByRootCauseLast.size() - 1; i >= 0; i--) {
        String message = messagesOrderedByRootCauseLast.get(i);

        if (isNotBlank(message)) {
          return message;
        }
      }
    }

    List<Throwable> alleGruende = getAlleGruende(t);
    return alleGruende.get(alleGruende.size() - 1).getMessage(); // LEGACY!
  }
}
