package cn.skcks.matrix.v2.advice;

import cn.skcks.matrix.v2.auth.claims.ClaimException;
import cn.skcks.matrix.v2.model.casbin.CasbinConstant;
import cn.skcks.matrix.v2.utils.json.JsonResponse;
import cn.skcks.matrix.v2.utils.json.ResponseStatus;
import jakarta.validation.ConstraintViolationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Objects;

/**
 * 全局异常处理类
 *
 * @author Shikong
 */
@RestControllerAdvice
public class ExceptionAdvice {
    private final static Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class);

    @ExceptionHandler(ClaimException.class)
    public JsonResponse<String> ClaimException(ClaimException e){
        return JsonResponse.build(ResponseStatus.UNAUTHORIZED, e.getMessage());
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    public JsonResponse<String> missingServletRequestParameterException(MissingServletRequestParameterException e) {
        return JsonResponse.error(e.getMessage());
    }

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public JsonResponse<String> httpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e){
        return JsonResponse.error(e.getMessage());
    }

    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    public JsonResponse<String> unsupportedMediaTypeException(Exception e) {
        e.printStackTrace();
        return JsonResponse.error(e.getMessage());
    }

    @ExceptionHandler(HttpMediaTypeNotAcceptableException.class)
    public JsonResponse<String> httpMediaTypeNotAcceptableException(HttpMediaTypeNotAcceptableException e){
        return JsonResponse.error(e.getMessage());
    }

    @ExceptionHandler(RuntimeException.class)
    public JsonResponse<String> runtimeException(RuntimeException e) {
        e.printStackTrace();
        return JsonResponse.error(e.getMessage());
    }

    @ExceptionHandler(BindException.class)
    public JsonResponse<String> handleValidationBindException(BindException e) {
        return JsonResponse.error(Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public JsonResponse<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        return JsonResponse.error(Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
    }

    @ExceptionHandler(ConstraintViolationException.class)
    public JsonResponse<String> handleConstraintViolationException(ConstraintViolationException e) {
        return JsonResponse.error(Objects.requireNonNull(e.getMessage()));
    }

    @ExceptionHandler(HttpMessageNotReadableException.class)
    public JsonResponse<String> handleHttpMessageNotReadableException(HttpMessageNotReadableException e){
        logger.warn("{}", e.getMessage());
        return JsonResponse.error("参数异常");
    }

    @ExceptionHandler(Exception.class)
    public JsonResponse<String> exception(Exception e) {
        e.printStackTrace();
        return JsonResponse.error(e.getMessage());
    }
}
