package net.northking.cctp.common.exception;

import cn.gjing.tools.auth.exception.PermissionAuthorizationException;
import cn.gjing.tools.auth.exception.RoleAuthorizationException;
import com.hzbank.testteam.autotest.dependencies.authDependency.utils.RequestUtil;
import com.hzbank.testteam.autotest.dependencies.baseDefineDependency.constants.BaseDefineDependencyConstants;
import com.hzbank.testteam.autotest.dependencies.baseDefineDependency.exception.InvalidException;
import com.hzbank.testteam.autotest.dependencies.baseDefineDependency.vo.ResponseVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 全局异常处理
 *
 * @author xiusong.xie
 * @since 1.0
 */
@RestControllerAdvice
public class ApiExceptionHandler
{
  private static final Logger log = LoggerFactory.getLogger(ApiExceptionHandler.class);
  /**
   * 没有权限处理
   *
   * @param e 没有权限异常
   * @return 没有权限错误
   */
  @ExceptionHandler(PermissionAuthorizationException.class)
  public ResponseVO permissionAuthorizationExceptionHandler(PermissionAuthorizationException e) {
    try {
      log.warn("用户无权限，拥有权限：" + RequestUtil.getPermissions() + "\n报错信息" + e);
    } catch (Exception exception) {
      //ignore
    }
    ResponseVO responseVO = new ResponseVO();
    responseVO.setCode(BaseDefineDependencyConstants.SYSTEM_RESPONSE_CODE_UN_AUTH);
    responseVO.setMessage("您的权限已发生变动，请刷新页面！");
    log.error(responseVO.toString());
    return responseVO;
  }

  /**
   * 没有角色处理
   *
   * @param e 没有角色异常
   * @return 没有角色错误
   */
  @ExceptionHandler(RoleAuthorizationException.class)
  public ResponseVO roleAuthorizationExceptionHandler(RoleAuthorizationException e) {
    try {
      log.warn("用户无角色权限，拥有权限：" + RequestUtil.getPermissions() + "\n报错信息" + e);
    } catch (Exception exception) {
      //ignore
    }
    ResponseVO responseVO = new ResponseVO();
    responseVO.setCode(BaseDefineDependencyConstants.SYSTEM_RESPONSE_CODE_UN_AUTH);
    responseVO.setMessage("您的权限已发生变动，请刷新页面！");
    log.error(responseVO.toString());
    return responseVO;
  }

  /**
   * 上传文件大小超过处理
   *
   * @param e 上传文件大小超过异常
   * @return 上传文件大小超过错误
   */
  @ExceptionHandler(MaxUploadSizeExceededException.class)
  public ResponseVO maxUploadSizeExceededExceptionHandler(MaxUploadSizeExceededException e) {
    ResponseVO responseVO = new ResponseVO();
    responseVO.setCode(BaseDefineDependencyConstants.SYSTEM_RESPONSE_CODE_ERROR);
    responseVO.setMessage("上传总文件大小超过200MB或单个文件超过150MB");
    log.error(responseVO.toString());
    return responseVO;
  }

  /**
   * 参数校验失败处理
   *
   * @param e 参数校验失败异常
   * @return 参数校验失败错误
   */
  @ExceptionHandler(BindException.class)
  public ResponseVO<List<FieldError>> bindExceptionHandler(BindException e) {
    ResponseVO<List<FieldError>> responseVO = new ResponseVO<>();
    responseVO.setCode(BaseDefineDependencyConstants.SYSTEM_RESPONSE_CODE_UN_CHECKED);
    responseVO.setMessage("参数校验失败");
    responseVO.setData(e.getFieldErrors());
    log.error(responseVO.toString());
    return responseVO;
  }

  @ExceptionHandler(value = PlatformRuntimeException.class)
  public ResponseVO<Object> platformExceptionHandler(PlatformRuntimeException e) {
    log.error("", e);
    ResponseVO responseVO = new ResponseVO();
    responseVO.setCode(e.getError().getCode().toString());
    responseVO.setMessage(e.getMessage());
    return responseVO;
  }

  /**
   * 未登录异常处理
   *
   * @param e 未登录时异常
   * @return 异常处理
   */
  @ExceptionHandler(value = PlatformAuthException.class)
  public ResponseVO<String> authExceptionHandler(PlatformAuthException e)
  {
    ResponseVO<String> responseVO = new ResponseVO<>();
    responseVO.setCode(BaseDefineDependencyConstants.SYSTEM_RESPONSE_CODE_UN_LOGIN);
    responseVO.setMessage("您还未登录，请先登录");
    return responseVO;
  }

  /**
   * 未授权异常处理
   *
   * @param e 未授权异常
   * @return 异常处理
   */
  @ExceptionHandler(value = PlatformForbiddenException.class)
  public ResponseVO authExceptionHandler(PlatformForbiddenException e)
  {
    try {
      log.warn("用户无ui权限，拥有权限：" + RequestUtil.getPermissions() + "\n报错信息" + e);
    } catch (Exception exception) {
      //ignore
    }
    ResponseVO responseVO = new ResponseVO();
    responseVO.setCode(BaseDefineDependencyConstants.SYSTEM_RESPONSE_CODE_UN_AUTH);
    responseVO.setMessage("您的权限已发生变动，请刷新页面！");
    log.error(responseVO.toString());
    return responseVO;
  }

  /**
   * 参数校验失败处理
   *
   * @param e 参数校验失败异常
   * @return 参数校验失败错误
   */
  @ExceptionHandler(MethodArgumentNotValidException.class)
  public ResponseVO<List<FieldError>> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
    ResponseVO<List<FieldError>> responseVO = new ResponseVO<>();
    responseVO.setCode(BaseDefineDependencyConstants.SYSTEM_RESPONSE_CODE_UN_CHECKED);
    responseVO.setMessage("参数校验失败");
    responseVO.setData(e.getBindingResult().getFieldErrors());
    log.error(responseVO.toString());
    return responseVO;
  }

  /**
   * 全局业务异常处理
   *
   * @param e 业务异常
   * @return 业务异常
   */
  @ExceptionHandler(InvalidException.class)
  public ResponseVO invalidExceptionHandler(InvalidException e) {
    ResponseVO responseVO = new ResponseVO();
    responseVO.setCode(e.getCode());
    responseVO.setMessage(e.getMessage());
    responseVO.setData(e.getData());
    log.error(responseVO.toString());
    return responseVO;
  }
  /**
   * 未知异常处理
   *
   * @param e 未知异常
   * @return 未知异常错误
   */
  @ExceptionHandler(Exception.class)
  public ResponseVO exceptionHandler(Exception e) {
    String requestURL ="";
    try{
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        requestURL = request.getRequestURL().toString();
    }catch (Exception exception){
      //ignore
    }
    log.error("请求异常 " + requestURL, e);
    ResponseVO responseVO = new ResponseVO<>();
    responseVO.setCode(BaseDefineDependencyConstants.SYSTEM_RESPONSE_CODE_ERROR);
    responseVO.setMessage("请求失败");
    return responseVO;
  }
}
