package com.xxl.job.admin.config;

import java.sql.SQLException;

import javax.validation.ValidationException;

import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import com.persagy.common.enums.ResponseCode;
import com.persagy.common.exception.BusinessException;
import com.xxl.job.core.biz.model.ReturnT;

import lombok.extern.slf4j.Slf4j;


/**
 * @description 
 * @author zhangqiankun
 * @since 2020年8月26日:	下午5:17:08
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
	
	/**
	 * 空指针异常
	 */
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	@ExceptionHandler(NullPointerException.class)
	public ReturnT<String> handleNullPointerException(NullPointerException e) {
		log.error(e.getMessage(), e);
		return new ReturnT<String>(ReturnT.FAIL_CODE, e.getMessage());
	}
	
	/**
	 * 自定义业务异常
	 */
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	@ExceptionHandler(BusinessException.class)
	public ReturnT<String> handleBusinessRuntimeException(BusinessException e) {
		log.error(e.getMessage(), e);
		return new ReturnT<String>(ReturnT.FAIL_CODE, e.getErrorDesc());
	}

	/**
	 * 入参校验异常
	 */
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	@ExceptionHandler(MethodArgumentNotValidException.class)
	public ReturnT<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
		log.error(e.getMessage(), e);
		return new ReturnT<String>(ReturnT.FAIL_CODE, e.getBindingResult().getFieldError().getDefaultMessage());
	}

	/**
	 * 入参校验异常
	 */
	@ExceptionHandler(BindException.class)
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public ReturnT<String> handleBindException(BindException e) {
		log.error(e.getMessage(), e);
		return new ReturnT<String>(ReturnT.FAIL_CODE, e.getBindingResult().getFieldError().getDefaultMessage());
	}
	
	/**
	 * 参数校验异常，message 为手动抛出时定义的具体异常信息
	 */
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	@ExceptionHandler(ValidationException.class)
	public ReturnT<String> handleValidationException(ValidationException e) {
		log.error(e.getMessage(), e);
		return new ReturnT<String>(ReturnT.FAIL_CODE, e.getCause().getMessage());
	}
	
	/**
	 * 参数校验异常，message 为手动抛出时定义的具体异常信息
	 */
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	@ExceptionHandler(IllegalArgumentException.class)
	public ReturnT<String> handleIllegalArgumentException(IllegalArgumentException e) {
		log.error(e.getMessage(), e);
		return new ReturnT<String>(ReturnT.FAIL_CODE, e.getMessage());
	}
	
	/**
	 * URI请求链接没有映射
	 */
	@ResponseStatus(HttpStatus.NOT_FOUND)
	@ExceptionHandler(NoHandlerFoundException.class)
	public ReturnT<String> handleNoHandlerFoundException(NoHandlerFoundException e) {
		log.error(e.getMessage(), e);
		return new ReturnT<String>(ReturnT.FAIL_CODE, e.getMessage());
	}
	
	/**
	 *  body体未找到
	 */
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	@ExceptionHandler(HttpMessageNotReadableException.class)
	public ReturnT<String> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
		log.error(e.getMessage(), e);
		return new ReturnT<String>(ReturnT.FAIL_CODE, ResponseCode.A0402.getDesc());
	}
	
	@ExceptionHandler(SQLException.class)
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public ReturnT<String> SQLException(SQLException e) {
		log.error("sql语句异常", e);
		return new ReturnT<String>(ReturnT.FAIL_CODE, ResponseCode.C0341.getDesc());
	}
	
	/**
	 * 系统默认繁忙
	 */
	@ExceptionHandler(Exception.class)
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public ReturnT<String> handleException(Exception e) {
		log.error(e.getMessage(), e);
		return new ReturnT<String>(ReturnT.FAIL_CODE, ResponseCode.Z9999.getDesc());
	}
	
}
