package com.ssm.config;

import com.ssm.manage.response.GenericResponse;
import com.ssm.manage.response.ResponseCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
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.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * @Author zhuangchongyi
 * @Description 全局异常处理类
 * @Date 2020/8/28 17:31
 */
@RestController
@ControllerAdvice
@Slf4j
public class CustomExceptionHandler {


    @ExceptionHandler({BindException.class})
    public ResponseEntity<GenericResponse> bindException(BindException e) {
        log.error("异常信息: ", e);
        return new ResponseEntity<>(new GenericResponse(ResponseCode.MSG,Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage()),HttpStatus.METHOD_NOT_ALLOWED);
    }

    @ExceptionHandler({HttpMessageNotReadableException.class})
    public ResponseEntity<GenericResponse> bindException(HttpMessageNotReadableException e) {
        log.error("异常信息: ", e);
        return new ResponseEntity<>(new GenericResponse(ResponseCode.MSG,"参数错误："+e.getMessage()),HttpStatus.METHOD_NOT_ALLOWED);
    }


    @ExceptionHandler(Exception.class)
    public ResponseEntity<GenericResponse> exception(Exception e) {
        if(e instanceof HttpMessageNotReadableException){
            return new ResponseEntity<>(new GenericResponse(ResponseCode.MSG,"数据格式错误"+e.getMessage()),HttpStatus.INTERNAL_SERVER_ERROR);
        }
        log.error("异常信息: ", e);
        return new ResponseEntity<>(new GenericResponse(ResponseCode.MSG,"未知系统异常，请稍后重试"+e.getMessage()),HttpStatus.INTERNAL_SERVER_ERROR);
    }


    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public ResponseEntity<GenericResponse> servletException(HttpRequestMethodNotSupportedException e, HttpServletRequest request) {
        log.error("异常信息: ", e);
        return new ResponseEntity<>(new GenericResponse<>(ResponseCode.MSG,"请求方式不对： "+ request.getMethod() +","+ request.getServletPath()), HttpStatus.METHOD_NOT_ALLOWED);
    }




    /**
     * 参数不合法异常
     *
     * @param e
     * @return
     * @Description
     * @author
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<GenericResponse> handleException(MethodArgumentNotValidException e) {
        log.error("异常信息: ", e);
        BindingResult a = e.getBindingResult();
        List<ObjectError> list = a.getAllErrors();
        String errorMsg = "未知异常";
        if (CollectionUtils.isNotEmpty(list)) {
            errorMsg = list.get(0).getDefaultMessage();
        }
        return new ResponseEntity<>(new GenericResponse(ResponseCode.MSG,errorMsg),HttpStatus.BAD_REQUEST);
    }


    @ExceptionHandler(ValidationException.class)
    public ResponseEntity<GenericResponse> validationException(ValidationException e) {
        log.error("异常信息: ", e);
        if (e instanceof ConstraintViolationException) {
            ConstraintViolationException ex = (ConstraintViolationException) e;
            String msg = Arrays.toString(ex.getConstraintViolations().stream().map(ConstraintViolation::getMessage).toArray());
            return new ResponseEntity<>(new GenericResponse(ResponseCode.MSG,msg),HttpStatus.BAD_REQUEST);
        }
        return new ResponseEntity<>(new GenericResponse(ResponseCode.MSG,e.getMessage()),HttpStatus.BAD_REQUEST);

    }
}
