package com.muchinfo.mtp3century.exception;

import com.muchinfo.mtp3common.enumtype.GlobalExceptionEnum;
import com.muchinfo.mtp3century.utils.AjaxResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

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

/**
 *  全局异常的处理器@RestControllerAdvice
 *  @RestControllerAdvice 该注解是一个复合注解包括下面两个注解
 *  @ControllerAdvice  将控制所有的Controller层并拦截所有的异常
 *  @ResponseBody       将本类中所有方法的返回值转换为JSON
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    /**
     * 处理系统异常
     * @return
     *
     * catch (Exception e) {
     *             e.printStackTrace();
     *             return AjaxResult.me().setSuccess(false).setMessage("系统繁忙，请重试！");
     *         }
     */
    @ExceptionHandler(Exception.class)
    public AjaxResult exceptionHandler(Exception e){
        log.error(Arrays.toString(e.getStackTrace()));
        return AjaxResult.error(GlobalExceptionEnum.ERROR.getCode(), GlobalExceptionEnum.ERROR.getMessage(),"");
    }

    /**
     * 处理自定义业务异常
     * @return
     *
     * catch (GlobalException e) {
     *             e.printStackTrace();
     *             return AjaxResult.me().setSuccess(false).setMessage("系统繁忙，请重试！");
     *         }
     */
    @ExceptionHandler(GlobalException.class)
    public AjaxResult globalExceptionHandler(GlobalException e){
        log.error(Arrays.toString(e.getStackTrace()));
        return AjaxResult.error(e.getCode(), e.getGlobalMessage(),e.getLanguages());
    }


    /**
     * 处理校验对象时候的异常MethodArgumentNotValidException
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public AjaxResult globalExceptionHandler(MethodArgumentNotValidException e){
        // ((BeanPropertyBindingResult) e.bindingResult).errors.get(0).defaultMessage
        log.error(Arrays.toString(e.getStackTrace()));
        List<ObjectError> errors = e.getBindingResult().getAllErrors();
        // map()：对于流的一些中间业务操作就用此方法
        // ObjectError::getDefaultMessage：我只要流中对象的defaultMessage
        // errors.stream().map(o->o.getDefaultMessage())
        // Collectors.joining(",")：joining只对字符串生效，用其他类型会报错,把所有的得到的字符串使用逗号进行隔开并组合成一个字符串
        String messages = errors.stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(","));

        return AjaxResult.error(GlobalExceptionEnum.PARAM_ERROR.getCode(), messages,"");
    }

    /**
     * 处理校验接口参数时候的异常ConstraintViolationException
     * @param e
     * @return
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public AjaxResult globalExceptionHandler(ConstraintViolationException e){
        log.error(Arrays.toString(e.getStackTrace()));
        return AjaxResult.error(GlobalExceptionEnum.PARAM_ERROR.getCode(), e.getMessage(),"");
    }
}
