package com.zanxiang.game.module.sdk.handler;

import com.zanxiang.game.module.sdk.exception.TokenExpireException;
import com.zanxiang.module.util.exception.BaseException;
import com.zanxiang.module.util.pojo.ResultVO;
import com.zanxiang.module.web.util.ServletUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

/**
 * 全局异常代理
 *
 * @author bilingfeng
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * token失效异常
     */
    @ExceptionHandler(TokenExpireException.class)
    public ResultVO<?> tokenExpireException(TokenExpireException e) {
        return ResultVO.reLogin();
    }

    /**
     * 业务异常
     */
    @ExceptionHandler(BaseException.class)
    public ResultVO<?> baseException(BaseException e) {
        return ResultVO.fail(e.getMessage());
    }

    /**
     * http method错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public ResultVO<?> methodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        log.error("URL：{}, 请求 method：{}, 支持的 method：{}", ServletUtil.getRequest().getRequestURL(), ServletUtil.getRequest().getMethod(), e.getSupportedMethods());
        return ResultVO.fail("http method错误！");
    }

    /**
     * 自定义参数校验错误
     */
    @ExceptionHandler(BindException.class)
    public ResultVO<?> validatedBindException(BindException e) {
        log.error(e.getMessage(), e);
        String message = e.getAllErrors().get(0).getDefaultMessage();
        return ResultVO.fail(message);
    }

    /**
     * 自定义参数校验错误
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultVO<?> validExceptionHandler(MethodArgumentNotValidException e) {
        log.error(e.getMessage(), e);
        String message = e.getBindingResult().getFieldError().getDefaultMessage();
        return ResultVO.fail(message);
    }

    /**
     * 自定义参数校验错误
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public ResultVO<?> validExceptionHandler(HttpMessageNotReadableException e) {
        log.error(e.getMessage(), e);
        return ResultVO.fail("参数异常，请勿非法操作");
    }

    /**
     * 参数类型不匹配导致转换异常
     */
    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    public ResultVO<?> mismatchErrorHandler(MethodArgumentTypeMismatchException e) {
        log.error("方法:{},字段:{},参数:{},错误信息:{}", e.getParameter().getMethod(), e.getName(), e.getValue(), e.getMessage());
        return ResultVO.fail("请求参数异常，请勿非法操作");
    }

    /**
     * 空指针异常全局处理
     */
    @ExceptionHandler(NullPointerException.class)
    public ResultVO<?> validExceptionHandler(NullPointerException e) {
        log.error(e.getMessage(), e);
        e.printStackTrace();
        return ResultVO.fail("空指针异常，请勿非法操作");
    }
}
