package com.malk.server.common;

import com.malk.utils.UtilServlet;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;

/**
 * 通用错误类 [错误抛出与拦截详见 CatchException]
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class McException extends RuntimeException {

    private static final long serialVersionUID = 5131110381034275224L;

    private boolean success;

    private String code;

    private String message;

    // 错误来源
    private String source;

    public McException(McREnum rEnum) {
        this(rEnum.isSuc(), rEnum.getCode(), rEnum.getMsg());
    }

    public McException(String code, String message) {
        this(false, code, message);
    }

    public McException(boolean suc, String code, String message) {
        super(message);
        this.success = suc;
        this.code = code;
        this.message = message;
    }


    /// 断言错误: 自定义错误信息 ///

    /**
     * 错误断言: 枚举
     */
    public static void assertException(boolean isAssert, McREnum rEnum) {
        if (isAssert) {
            throw McException.builder().code(rEnum.getCode()).message(rEnum.getMsg()).build();
        }
    }

    /**
     * 错误断言: 信息
     */
    public static void assertException(boolean isAssert, String code, String message) {
        if (isAssert) {
            throw McException.builder().code(code).message(message).build();
        }
    }

    /**
     * 错误断言: 来源
     */
    public static void assertException(boolean isAssert, String code, String message, String source) {
        if (isAssert) {
            throw McException.builder().code(code).message(message).source(source).build();
        }
    }

    /**
     * 断言: 业务校验不通过
     */
    public static void
    assertAccessException(boolean isAssert, String message) {
        if (isAssert) {
            throw McException.builder().code(McREnum.VALIDATED_ACCESS.getCode()).message(message).build();
        }
    }

    /**
     * 断言: 参数校验不通过
     */
    public static void assertParamException(boolean isAssert, String message) {
        if (isAssert) {
            throw McException.builder().code(McREnum.VALIDATED_PARAM.getCode()).message(message).build();
        }
    }

    /**
     * 断言: 参数不合法
     * -
     * 实例: McException.assertParamException_Null(UtilServlet.isNull(param, "projectName", "userName"));
     */
    public static void assertParamException_Null(String key) {
        if (StringUtils.isNotBlank(key)) {
            throw McException.builder().code(McREnum.VALIDATED_PARAM.getCode()).message(("参数不能为空: ").concat(key)).build();
        }
    }

    public static void assertParamException_Null(Map param, String... keys) {
        McException.assertParamException_Null(UtilServlet.isNull(param, keys));
    }

    public static void assertParamException_Null(Map param, String keys) {
        McException.assertParamException_Null(UtilServlet.isNull(param, keys));
    }

    /**
     * 断言: 参数不能为空
     */
    public static void assertParamException_Rule(String key) {
        if (StringUtils.isNotBlank(key)) {
            throw McException.builder().code(McREnum.VALIDATED_PARAM.getCode()).message(("参数不合法: ").concat(key)).build();
        }
    }

    /// 快速枚举: 自定义错误信息 ///

    /**
     * 参数不合法
     */
    public static McR exceptionParam(String message) {
        throw McException.builder().code(McREnum.VALIDATED_PARAM.getCode()).message(message).build();
    }

    /**
     * 无效token
     */
    public static McR exceptionToken(String message) {
        throw McException.builder().code(McREnum.TOKEN_INVALID.getCode()).message(message).build();
    }

    /**
     * 授权无效
     */
    public static McR exceptionAuth(String message) {
        throw McException.builder().code(McREnum.NOT_AUTHORIZED.getCode()).message(message).build();
    }

    /**
     * 业务校验不通过
     */
    public static McR exceptionAccess(String message) {
        throw McException.builder().code(McREnum.VALIDATED_ACCESS.getCode()).message(message).build();
    }

    /**
     * 方法执行失败
     */
    public static McR exceptionExecute(String message) {
        throw McException.builder().code(McREnum.METHOD_EXECUTE.getCode()).message(message).build();
    }

    /**
     * 未知错误
     */
    public static McR exceptionUnknown(String message) {
        throw McException.builder().code(McREnum.UNKNOWN_EXCEPTION.getCode()).message(message).build();
    }
}
