package com.ningdatech.carapi.common.handler;

import com.ningdatech.basic.enumeration.Status;
import com.ningdatech.basic.model.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
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 org.springframework.web.servlet.NoHandlerFoundException;

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

/**
 * @description: 统一错误处理
 * @author: liushuai
 * @date: 2022/3/25 11:39
 */
@Slf4j
@ControllerAdvice
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class GlobalExceptionHandler {

    @ResponseBody
    @ExceptionHandler(value = NoHandlerFoundException.class)
    public ApiResponse<Void> noHandlerFoundException(NoHandlerFoundException e) {
        log.error("【全局异常拦截】NoHandlerFoundException: 请求方法 {}, 请求路径 {}", e.getRequestURL(), e.getHttpMethod());
        return ApiResponse.ofStatus(Status.REQUEST_NOT_FOUND);
    }

    @ResponseBody
    @ExceptionHandler(value = {MethodArgumentNotValidException.class, BindException.class})
    public ApiResponse<Void> bindException(BindException e) {
        String msg = e.getAllErrors().stream()
                .map(DefaultMessageSourceResolvable::getDefaultMessage)
                .collect(Collectors.joining(","));
        return ApiResponse.of(Status.BAD_REQUEST.getCode(), msg, null);
    }

    @ResponseBody
    @ExceptionHandler(value = ConstraintViolationException.class)
    public ApiResponse<Void> constraintViolationException(ConstraintViolationException e) {
        String msg = e.getConstraintViolations().stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.joining(","));
        return ApiResponse.of(Status.BAD_REQUEST.getCode(), msg, null);
    }

    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ApiResponse<Void> handlerException(Exception e) {
        log.error("【全局异常拦截】: 异常信息 {}: {} ", e.getClass().getSimpleName(), e);
        return ApiResponse.of(Status.BAD_REQUEST.getCode(), e.getMessage(), null);
    }

}
