package com.ruoyi.framework.exception;

import com.ruoyi.framework.web.domain.AjaxResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;

@ControllerAdvice
public class GlobalExceptionAdvice {
    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionAdvice.class);

    /**
     * 校验错误拦截处理
     * 处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常
     *
     * @param exception 错误信息集合
     * @return 错误信息
     */
    @ResponseBody
    @ExceptionHandler(BindException.class)
    //@ResponseStatus(HttpStatus.BAD_REQUEST)
    public AjaxResult bindExceptionHandler(BindException exception) {
        LOGGER.error("BindException encountered: {0}", exception);
        String message =
                exception.getBindingResult().getAllErrors().stream()
                        .map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
        return AjaxResult.error(message);
    }

    /**
     * 校验错误拦截处理
     * 处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是javax.validation.ConstraintViolationException
     *
     * @param exception 错误信息集合
     * @return 错误信息
     */
    @ResponseBody
    @ExceptionHandler(ConstraintViolationException.class)
    //@ResponseStatus(HttpStatus.BAD_REQUEST)
    public AjaxResult constraintViolationHandler(ConstraintViolationException exception) {
        LOGGER.error("ConstraintViolation exception encountered: {0}", exception);
        //return BaseResponse.newError("YourProjectName_ConstraintViolation", exception.getMessage());
        return AjaxResult.error(exception.getMessage());
    }

    /**
     * 校验错误拦截处理
     * 处理请求参数格式错误 @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常。
     *
     * @param exception 错误信息集合
     * @return 错误信息
     */
    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    //@ResponseStatus(HttpStatus.BAD_REQUEST)
    public AjaxResult methodArgumentNotValidHandler(MethodArgumentNotValidException exception) {
        LOGGER.error("MethodArgumentNotValid exception encountered: {0}", exception);
        BindingResult bindingResult = exception.getBindingResult();
        StringBuilder sb = new StringBuilder();
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            sb.append(fieldError.getField()).append(": ").append(fieldError.getDefaultMessage()).append(", ");
        }
        //return BaseResponse.newError("YourProjectName_MethodArgumentNotValid", sb.toString());
        return AjaxResult.error(sb.toString());
    }
}