package com.base.orbit.Exception;

import lombok.Getter;
import org.springframework.context.support.ResourceBundleMessageSource;

import java.nio.charset.StandardCharsets;
import java.util.Locale;

/**
 * 公交统一异常, 强制指定错误码
 *
 * @author jhzhu
 * @date 2022-02-11
 * @see ErrorCode
 */
@Getter
public class OrbitException extends RuntimeException {

    private static final long serialVersionUID = 981907209562008714L;

    public static final ResourceBundleMessageSource MESSAGE_SOURCE = new ResourceBundleMessageSource();
    static {
        OrbitException.MESSAGE_SOURCE.setDefaultEncoding(StandardCharsets.UTF_8.name());
        OrbitException.MESSAGE_SOURCE.setUseCodeAsDefaultMessage(true);
        // 按需添加各个子module的错误文件
        OrbitException.MESSAGE_SOURCE.setBasenames("i18n.errors_common", "i18n.errors_baseplatform");
    }

    private final ErrorCode errorCode;

    /** 不含错误码的错误消息 */
    private String errorMsgWithoutErrorCode;

    public OrbitException() {
        this(DefaultSystemErrorCodeEnum.DEFAULT_ERROR);
    }

    public OrbitException(String errMsg) {
        super(errMsg);
        this.errorCode = DefaultSystemErrorCodeEnum.DEFAULT_ERROR;
        this.errorMsgWithoutErrorCode = errMsg;
    }

    public OrbitException(Throwable cause) {
        this(DefaultSystemErrorCodeEnum.DEFAULT_ERROR, cause);
    }

    public OrbitException(ErrorCode errorCode) {
        super(String.format("%s:%s", errorCode.getCode(), errorCode.getErrorMessageContent()));
        this.errorCode = errorCode;
        this.errorMsgWithoutErrorCode = errorCode.getErrorMessageContent();
    }

    public OrbitException(ErrorCode errorCode, String... args) {
        super(String.format("%s:%s", errorCode.getCode(), errorCode.getErrorMessageContent(args)));
        this.errorCode = errorCode;
        this.errorMsgWithoutErrorCode = errorCode.getErrorMessageContent(args);
    }

    public OrbitException(ErrorCode errorCode, Locale locale) {
        super(String.format("%s:%s", errorCode.getCode(), errorCode.getErrorMessageContent(locale)));
        this.errorCode = errorCode;
        this.errorMsgWithoutErrorCode = errorCode.getErrorMessageContent(locale);
    }

    public OrbitException(ErrorCode errorCode, Throwable cause) {
        super(String.format("%s:%s", errorCode.getCode(), errorCode.getErrorMessageContent()), cause);
        this.errorCode = errorCode;
        this.errorMsgWithoutErrorCode = errorCode.getErrorMessageContent();
    }

    public OrbitException(ErrorCode errorCode, Locale locale, Throwable cause) {
        super(String.format("%s:%s", errorCode.getCode(), errorCode.getErrorMessageContent(locale)), cause);
        this.errorCode = errorCode;
        this.errorMsgWithoutErrorCode = errorCode.getErrorMessageContent(locale);
    }

    public OrbitException(ErrorCode errorCode, Throwable cause, String... args) {
        super(String.format("%s:%s", errorCode.getCode(), errorCode.getErrorMessageContent(args)), cause);
        this.errorCode = errorCode;
        this.errorMsgWithoutErrorCode = errorCode.getErrorMessageContent(args);
    }

    public OrbitException(ErrorCode errorCode, Locale locale, Throwable cause, String... args) {
        super(String.format("%s:%s", errorCode.getCode(), errorCode.getErrorMessageContent(args, locale)), cause);
        this.errorCode = errorCode;
        this.errorMsgWithoutErrorCode = errorCode.getErrorMessageContent(args, locale);
    }
}
