package com.ruoyi.common.exception;

import java.util.Map;
import java.util.Objects;

/**
 * 断言异常
 * 
 * @author zhao
 */
public final class ASSERT extends RuntimeException
{
    private static final long serialVersionUID = 1L;

    public final String message;

    public ASSERT(String message)
    {
        this.message = message;
    }

    @Override
    public String getMessage()
    {
        return message;
    }

    public static String Output(ASSERT e)
    {
        StringBuilder sb = new StringBuilder();
        sb.append(e.message);
        StackTraceElement[] stackTrace = e.getStackTrace();
        if(null != stackTrace)
        {
            for(int i = 0; i < stackTrace.length; i++)
            {
                StackTraceElement st = stackTrace[i];
                if(st.getClassName().startsWith("com.ruoyi."))
                {
                    sb.append("\n").append("\t").append(i).append(": ").append(st.toString());
                }
            }
        }
        return sb.toString();
    }

    public static void THROW(String message, Object...args)
    {
        throw new ASSERT(null != message ? String.format(message, args) : "断言失败");
    }

    public static void EXP(boolean expression, String errorMsgTemplate, Object... params) throws ASSERT {
        if(!expression)
            THROW(errorMsgTemplate, params);
    }
    public static void EXP(boolean expression) throws ASSERT {
        EXP(expression, "断言表达式为假");
    }

    public static void TRUE(boolean expression, String errorMsgTemplate, Object... params) throws ASSERT {
        if(!expression)
            THROW(errorMsgTemplate, params);
    }

    public static void TRUE(boolean expression) throws ASSERT {
        TRUE(expression, "[断言失败] - 表达式必须为true");
    }

    public static void FALSE(boolean expression, String errorMsgTemplate, Object... params) throws ASSERT {
        if(expression)
            THROW(errorMsgTemplate, params);
    }

    public static void FALSE(boolean expression) throws ASSERT {
        FALSE(expression, "[断言失败] - 表达式必须false");
    }

    public static void NULL(Object object, String errorMsgTemplate, Object... params) throws ASSERT {
        if(Objects.nonNull(object))
            THROW(errorMsgTemplate, params);
    }

    public static void NULL(Object object) throws ASSERT {
        NULL(object, "[断言失败] - 对象必须为null");
    }

    public static <T> T NONNULL(T object, String errorMsgTemplate, Object... params) throws ASSERT {
        if(Objects.isNull(object))
            THROW(errorMsgTemplate, params);
        return object;
    }

    public static <T> T NONNULL(T object) throws ASSERT {
        return NONNULL(object, "[断言失败] - 对象必须非null");
    }

    public static String NOTEMPTY(String text, String errorMsgTemplate, Object... params) throws ASSERT {
        if(null == text || text.isEmpty() || text.trim().isEmpty())
            THROW(errorMsgTemplate, params);
        return text;
    }

    public static String NOTEMPTY(String text) throws ASSERT {
        return NOTEMPTY(text, "[断言失败] - 字符串必须有非空字符数");
    }

    public static String EMPTY(String text, String errorMsgTemplate, Object... params) throws ASSERT {
        if(null != text && !text.isEmpty() && !text.trim().isEmpty())
            THROW(errorMsgTemplate, params);
        return text;
    }

    public static String EMPTY(String text) throws ASSERT {
        return EMPTY(text, "[断言失败] - 字符串必须不能包含非空字符");
    }

    public static <T> T[] NOTEMPTY(T[] array, String errorMsgTemplate, Object... params) throws ASSERT {
        if(null == array || array.length == 0)
            THROW(errorMsgTemplate, params);
        return array;
    }

    public static <T> T[] NOTEMPTY(T[] array) throws ASSERT {
        return NOTEMPTY(array, "[断言失败] - 数组必须非空");
    }

    public static <T> Iterable<T> NOTEMPTY(Iterable<T> collection, String errorMsgTemplate, Object... params) throws ASSERT {
        if(null == collection || !collection.iterator().hasNext() )
            THROW(errorMsgTemplate, params);
        return collection;
    }

    public static <T> Iterable<T> NOTEMPTY(Iterable<T> collection) throws ASSERT {
        return NOTEMPTY(collection, "[断言失败] - 集合容器必须非空");
    }

    public static <K, V> Map<K, V> NOTEMPTY(Map<K, V> map, String errorMsgTemplate, Object... params) throws ASSERT {
        if(null == map || map.isEmpty() )
            THROW(errorMsgTemplate, params);
        return map;
    }

    public static <K, V> Map<K, V> NOTEMPTY(Map<K, V> map) throws ASSERT {
        return NOTEMPTY(map, "[断言失败] - 关联容器必须非空");
    }
}