package com.inspect.common.security.handler;

import com.inspect.base.core.exception.DemoModeException;
import com.inspect.base.core.exception.InnerAuthException;
import com.inspect.base.core.exception.ServiceException;
import com.inspect.base.core.exception.auth.NotPermissionException;
import com.inspect.base.core.exception.auth.NotRoleException;
import com.inspect.base.core.utils.StringUtils;
import com.inspect.base.core.web.domain.AjaxResult;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
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;

//@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler({NotPermissionException.class})
    public AjaxResult handleNotPermissionException(NotPermissionException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        String errStr = String.format("URI[{%s}] Auth Fail:{%s}", requestURI, e.getMessage());
        log.error(errStr);
        return AjaxResult.error(403, errStr);
    }

    @ExceptionHandler({NotRoleException.class})
    public AjaxResult handleNotRoleException(NotRoleException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        String errStr = String.format("URI[{%s}] Role Fail:{%s}", requestURI, e.getMessage());
        log.error(errStr);
        return AjaxResult.error(403, errStr);
    }

    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        String errStr = String.format("URI[{%s}] Not Support:{%s}", requestURI, e.getMessage());
        log.error(errStr);
        return AjaxResult.error(errStr);
    }

    @ExceptionHandler({ServiceException.class})
    public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) {
        log.error(e.getMessage(), e);
        Integer code = e.getCode();
        return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
    }

    @ExceptionHandler({RuntimeException.class})
    public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        String errStr = String.format("URI[{%s}] Unknown Exception:{%s}", requestURI, e.getMessage());
        e.printStackTrace();
        log.error(errStr);
        return AjaxResult.error(errStr);
    }

    @ExceptionHandler({Exception.class})
    public AjaxResult handleException(Exception e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        String errStr = String.format("URI[{%s}] System Exception:{%s}", requestURI, e.getMessage());
        log.error(errStr);
        return AjaxResult.error(errStr);
    }

    @ExceptionHandler({BindException.class})
    public AjaxResult handleBindException(BindException e) {
        log.error(e.getMessage(), e);
        String message = e.getAllErrors().get(0).getDefaultMessage();
        return AjaxResult.error(message);
    }

    @ExceptionHandler({MethodArgumentNotValidException.class})
    public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error(e.getMessage(), e);
        String message = e.getBindingResult().getFieldError().getDefaultMessage();
        return AjaxResult.error(message);
    }

    @ExceptionHandler({InnerAuthException.class})
    public AjaxResult handleInnerAuthException(InnerAuthException e) {
        return AjaxResult.error(e.getMessage());
    }

    @ExceptionHandler({DemoModeException.class})
    public AjaxResult handleDemoModeException(DemoModeException e) {
        return AjaxResult.error("Demo mode, Exclusion!");
    }
}
