package com.sy.coinage.core.exceptionhandler;

import javax.servlet.http.HttpServletRequest;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import com.sy.coinage.core.constants.ResponseEnum;
import com.sy.coinage.core.exception.RetException;
import com.sy.coinage.core.resp.ReturnJson;
import com.sy.coinage.core.util.CommUtils;

@Slf4j
@RestControllerAdvice
public class HandlerExceptionControllerAdvice {

    /**
     * -ResponseEntityExceptionHandler -处理自定义异常
     */
    @ExceptionHandler({RetException.class})
    public ReturnJson handlerRetException(HttpServletRequest request, Exception ex) {
        ReturnJson response = ReturnJson.Faild;
        Integer statusCode;
        RetException retException = (RetException) ex;
        if (retException.getResponseEnum() == null) {
            statusCode = ResponseEnum.FAILED.value();
        } else {
            statusCode = retException.getResponseEnum().value();
        }
        response.setCode(statusCode);
        response.setMsg(retException.getMessage());
        return response;
    }

    /**
     * -记录日志
     *
     * @param request
     * @return
     */
    private Object log(HttpServletRequest request) {
        String errorKey = "org.springframework.boot.web.servlet.error.DefaultErrorAttributes.ERROR";
        Object error = request.getAttribute(errorKey);
        if (error != null) {
            CommUtils.WebErrorLog(log, (Throwable) error, request);
        }
        return error;
    }

    /**
     * -处理请求的方法不存在异常
     */
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public ReturnJson handlerHttpRequestMethodNotSupportedException(HttpServletRequest request, Exception ex) {
        ReturnJson response = ReturnJson.Faild;
        response.setCode(ResponseEnum.FAILED.value());
        response.setMsg(ResponseEnum.FAILED.getMsg() + " Request method '" + request.getMethod() + "' not supported");
        return response;
    }

    @ExceptionHandler({NoHandlerFoundException.class})
    public ReturnJson handlerNoHandlerFoundExceptionn(HttpServletRequest request, Exception ex) {
        ReturnJson response = ReturnJson.Faild;
        NoHandlerFoundException e = (NoHandlerFoundException) ex;
        response.setCode(ResponseEnum.FAILED.value());
        response.setMsg(e.getLocalizedMessage());
        return response;
    }

    @ExceptionHandler({HttpMediaTypeNotSupportedException.class})
    public ReturnJson handlerHttpMediaTypeNotSupportedException(HttpServletRequest request, Exception ex) {
        ReturnJson response = ReturnJson.Faild;
        response.setCode(ResponseEnum.FAILED.value());
        response.setMsg(ResponseEnum.FAILED.getMsg() + " Content type '" + request.getHeader("Content-Type")
                        + "' not supported");
        return response;
    }

    @ExceptionHandler({MissingServletRequestParameterException.class})
    public ReturnJson handlerMissingServletRequestParameterException(HttpServletRequest request, Exception ex) {
        ReturnJson response = ReturnJson.Faild;
        MissingServletRequestParameterException e = (MissingServletRequestParameterException) ex;
        response.setCode(ResponseEnum.FAILED.value());
        response.setMsg(e.getParameterName() + "不能为空");
        return response;
    }

    /**
     * -处理请求参数验证错误异常
     */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public ReturnJson handlerValiException(HttpServletRequest request, Exception ex) {
        ReturnJson response = ReturnJson.Faild;
        MethodArgumentNotValidException e = (MethodArgumentNotValidException) ex;
        response.setCode(ResponseEnum.QUERY_PARAM_INVALID.value());
        response.setMsg(ResponseEnum.QUERY_PARAM_INVALID.getMsg() + ","
                        + e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
        return response;
    }

    /**
     * -处理未知异常
     */
    @ExceptionHandler({Exception.class})
    public ReturnJson handlerException(HttpServletRequest request, Exception ex) {
        log(request);
        ReturnJson response = ReturnJson.Faild;
        response.setCode(ResponseEnum.FAILED.value());
        response.setMsg(ex.getMessage());
        return response;
    }

}
