package org.example.Utils;

import org.example.Entity.CusException.CusException;

public class ExtentionsUtil {
    public static String getErrMsg(Throwable e, boolean stackTrace) {
        // 处理内部异常
        if (e.getCause() != null) {
            String msg = getErrMsg(e.getCause(), stackTrace);
            if (msg.contains("{0}")) {
                // 替换占位符，对应C#的字符串替换逻辑
                String replacement = (e instanceof CusException) ? "" : "\n" + e.getMessage();
                return msg.replace("{0}", replacement);
            }
            return msg;
        }

        // 构建基础异常信息
        StringBuilder sb = new StringBuilder();
        sb.append(e.getMessage() != null ? e.getMessage() : e.toString());
        sb.append("{0}");

        // 追加堆栈信息（如果需要）
        if (stackTrace) {
            sb.append("\n").append(getStackTrace(e));
        }

        return sb.toString();
    }

    /**
     * 简化版getErrMsg，不包含堆栈信息
     */
    public static String getErrMsg(Throwable e) {
        return getErrMsg(e, false);
    }

    /**
     * 获取异常堆栈信息，对应C#的GetErrStack扩展方法
     * @param e 异常对象
     * @return 堆栈信息字符串
     */
    public static String getErrStack(Throwable e) {
        StringBuilder sb = new StringBuilder();

        // 获取当前异常的堆栈信息
        sb.append(getStackTrace(e));

        // 递归处理内部异常
        if (e.getCause() != null) {
            sb.append("\n").append(getErrStack(e.getCause()));
        }

        return sb.toString();
    }

    /**
     * 辅助方法：获取异常的堆栈信息字符串
     */
    private static String getStackTrace(Throwable e) {
        StringBuilder sb = new StringBuilder();
        appendStackTrace(e, sb, "");
        return sb.toString();
    }

    private static void appendStackTrace(Throwable throwable, StringBuilder sb, String caption) {
        if (throwable == null) {
            return;
        }
        if (!caption.isEmpty()) {
            sb.append(caption);
        }
        sb.append(throwable).append(System.lineSeparator());
        for (StackTraceElement element : throwable.getStackTrace()) {
            sb.append("\tat ").append(element).append(System.lineSeparator());
        }
        for (Throwable suppressed : throwable.getSuppressed()) {
            appendStackTrace(suppressed, sb, "Suppressed: ");
        }
        if (throwable.getCause() != null) {
            appendStackTrace(throwable.getCause(), sb, "Caused by: ");
        }
    }
}
