package com.pcloud.common.core.exception;

import javax.servlet.http.HttpServletRequest;

import org.apache.catalina.connector.ClientAbortException;
import org.codehaus.jackson.JsonParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.pcloud.common.dto.ResponseDto;
import com.pcloud.common.exceptions.BizException;
import com.pcloud.common.permission.PermissionException;

import feign.FeignException;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

/**
 * 
 * @描述：异常集中处理
 * @作者：songx
 * @创建时间：2017年9月11日,下午6:41:27 @版本：1.0
 */
@ControllerAdvice
public class GlobalExceptionHandler {

	/**
	 * 
	 */
	private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);

	/**
	 * 异常处理
	 * 
	 * @param request
	 * @param exception
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@ExceptionHandler(value = Exception.class)
	public ResponseEntity<Object> exceptionHandler(HttpServletRequest request, Exception exception) throws Exception {
		// 请求方式不支持
		if (exception instanceof HttpRequestMethodNotSupportedException) {
			LOGGER.warn("【http请求异常】" + exception.getMessage(), exception);
			return new ResponseEntity<>("请求方式非法", HttpStatus.BAD_REQUEST);
		}

		//json参数解析错误
		else if (exception instanceof HttpMessageNotReadableException) {
			LOGGER.warn("【http请求json参数有误】" + exception.getMessage(), exception);
			return new ResponseEntity<>("json参数有误", HttpStatus.BAD_REQUEST);
		}

		// 请求异常
		else if (exception instanceof ServletRequestBindingException) {
			LOGGER.warn("【servlet请求异常】" + exception.getMessage(), exception);
			return new ResponseEntity<>(exception.getMessage(), HttpStatus.BAD_REQUEST);
		}
		// 数字转换异常
		else if (exception instanceof MethodArgumentTypeMismatchException) {
			LOGGER.warn("【参数异常】" + exception.getMessage(), exception);
			return new ResponseEntity<>(exception.getMessage(), HttpStatus.BAD_REQUEST);
		}
		// 内部调用异常
		else if (exception instanceof FeignException) {
			LOGGER.info("【内部调用异常】" + exception.getMessage(), exception);
			return new ResponseEntity<>(exception.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
		}
		// 权限异常
		else if (exception instanceof PermissionException) {
			LOGGER.warn("【权限异常】" + exception.getMessage(), exception);
			PermissionException permissionException = (PermissionException) exception;
			ResponseDto<Object> responseDto = new ResponseDto<>();
			responseDto.setErrCode(permissionException.getCode());
			responseDto.setMessage(permissionException.getMessage());
			return new ResponseEntity<>(responseDto, HttpStatus.UNAUTHORIZED);
		}
		// json解析异常
		else if (exception instanceof JsonParseException) {
			LOGGER.warn("【解析异常】" + exception.getMessage(), exception);
			return new ResponseEntity<>("Json解析错误，请检查参数！", HttpStatus.INTERNAL_SERVER_ERROR);
		} else if (exception instanceof ClientAbortException) {
			// 用户在结果返回之前提前结束请求或者刷新
			LOGGER.warn("【响应未结束】" + exception.getMessage(), exception);
			return new ResponseEntity<>("响应未结束!", HttpStatus.OK);
		}
		// 业务异常
		else if (exception instanceof BizException) {
			LOGGER.info("【业务异常】" + exception.getMessage(), exception);
			BizException bizException = (BizException) exception;
			ResponseDto<Object> responseDto = new ResponseDto<>();
			responseDto.setErrCode(bizException.getCode());
			responseDto.setMessage(bizException.getMessage());
			return new ResponseEntity<>(responseDto, HttpStatus.OK);
		} else {
			LOGGER.error("【服务异常】" + exception.getMessage(), exception);
			return new ResponseEntity<>("系统繁忙,请稍后再试!", HttpStatus.INTERNAL_SERVER_ERROR);
		}
	}

}
