package net.vtstar.zhongtong.avi.global.advice;

import lombok.extern.slf4j.Slf4j;
import net.vtstar.user.exception.KnownRuntimeException;
import net.vtstar.utils.domain.Return;
import net.vtstar.utils.exception.KnownException;
import org.apache.ibatis.exceptions.PersistenceException;
import org.mybatis.spring.MyBatisSystemException;
import org.springframework.core.annotation.Order;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.lang.reflect.InvocationTargetException;
import java.util.List;

@Slf4j
@Order(1)
@RestControllerAdvice("net.vtstar")
public class BaseExceptionAdvice {

	@ExceptionHandler(value = Exception.class)
	public Return ExceptionHandler(Exception e) {
		log.error(e.getMessage());
		if (e instanceof BindException) {
			BindException ex = (BindException) e;
			List<ObjectError> allErrors = ex.getAllErrors();//捕获的所有错误对象
			ObjectError error = allErrors.get(0);
			String defaultMessage = error.getDefaultMessage();//异常内容
			return Return.failed(defaultMessage);
		} else if (e instanceof MethodArgumentNotValidException) {
			MethodArgumentNotValidException ex = (MethodArgumentNotValidException) e;
			List<ObjectError> errors = ex.getBindingResult().getAllErrors();
			String message = errors.get(0).getDefaultMessage();
			return Return.failed(message);
		} else if (e instanceof IllegalArgumentException) {
			return Return.failed(e.getMessage());
		} else if (e instanceof IllegalStateException) {
			return Return.failed(e.getMessage());
		} else if (e instanceof KnownException) {
			return Return.failed(e.getMessage());
		} else if (e instanceof KnownRuntimeException) {
			return Return.failed(e.getMessage());
		} else if (e instanceof MyBatisSystemException) {
			MyBatisSystemException ex = (MyBatisSystemException) e;
			if (ex.getCause() instanceof PersistenceException) {
				PersistenceException pex = (PersistenceException) ex.getCause();
				if (pex.getCause() instanceof KnownRuntimeException) {
					return Return.failed(pex.getCause().getMessage());
				} else if (pex.getCause() instanceof InvocationTargetException) {
					InvocationTargetException iex = (InvocationTargetException) pex.getCause();
					if (iex != null && iex.getCause() != null
							&& iex.getCause() instanceof KnownRuntimeException) {
						return Return.failed(iex.getCause().getMessage());
					}
				}
			}
			log.error(e.getMessage(), e);
			return Return.failed("内部错误");
		} else {
			log.error(e.getMessage(), e);
			return Return.failed("内部错误");
		}
	}
}
