package de.duehl.basics.system;

/*
 * Copyright 2018 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import de.duehl.basics.text.Text;
import de.duehl.basics.text.html.generation.HtmlBuilder;

/**
 * Diese Klasse stellt Hilfsmethoden rund um Ausnahmen zur Verfügung.
 *
 * @version 1.01     2018-09-26
 * @author Christian Dühl
 */

public class ExceptionHelper {

    private ExceptionHelper() {}

    /**
     * Stellt einen mehrzeiligen String zusammen mit der Ausnahme, ihrem Stacktrace und ihren
     * eventuell vorhandenen Ursachen (Causes).
     */
    public static String getDescriptionWithStackTrace(Throwable exception) {
        StringBuilder descriptionBuilder = new StringBuilder();

        Class<?> classs = exception.getClass();
        String className = classs.getName();
        descriptionBuilder.append("Klassenname: ").append(className).append(Text.LINE_BREAK);

        String message = exception.getMessage();
        descriptionBuilder.append("Nachricht  : ").append(message).append(Text.LINE_BREAK);

        descriptionBuilder.append("Stack-Trace: ").append(Text.LINE_BREAK);
        int count = 0;
        for (StackTraceElement ste : exception.getStackTrace()) {
            descriptionBuilder.append(String.format("%6d: ", ++count)).append(ste.toString())
                    .append(Text.LINE_BREAK);
        }

        Throwable cause = exception.getCause();
        if (null != cause) {
            descriptionBuilder.append("Cause      : ").append(Text.LINE_BREAK)
                    .append(getDescriptionWithStackTrace(cause));
        }

        return descriptionBuilder.toString();
    }

    /**
     * Stellt einen mehrzeiligen String zusammen mit der Ausnahme, ihrem Stacktrace und ihren
     * eventuell vorhandenen Ursachen (Causes).
     */
    public static String getDescriptionWithStackTraceHtml(Throwable exception) {
        HtmlBuilder html = new HtmlBuilder();

        Class<?> classs = exception.getClass();
        String className = classs.getName();
        html.appendP("Klassenname: " + className);

        String message = exception.getMessage();
        html.appendP("Nachricht  : " + message);

        html.appendP("Stack-Trace:");
        html.appendOpeningOl();
        for (StackTraceElement ste : exception.getStackTrace()) {
            html.appendLi(ste.toString());
        }
        html.appendClosingOl();

        Throwable cause = exception.getCause();
        if (null != cause) {
            html.appendP("Cause      :").append(getDescriptionWithStackTraceHtml(cause));
        }

        return html.toString();
    }

    /**
     * Erstellt einen einzeiligen String mit Klasse und Fehlertext der Ausnahme, ihrem
     * Stacktrace und ihren eventuell vorhandenen Ursachen (Causes).
     */
    public static String getExceptionNameAndMessage(Throwable exception) {
        StringBuilder builder = new StringBuilder();
        builder.append("Klasse der Ausnahme: " + exception.getClass().getName())
               .append(", ")
               .append("Fehlermeldung der Ausnahme: " + exception.getMessage());

        Throwable cause = exception.getCause();
        if (null != cause) {
            builder.append(" (caused by: ")
                    .append(getExceptionNameAndMessage(cause))
                    .append(")");
        }

        return builder.toString();
    }

}
