package com.ho.user.aop;

import com.ho.common.tools.exception.BaseResponseCode;
import com.ho.common.tools.exception.BusinessException;
import com.ho.common.tools.exception.DataResult;
import org.apache.shiro.authz.AuthorizationException;
import org.hibernate.validator.internal.engine.path.PathImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;

/**
 * @描述 全局异常处理
 * @创建人 fancl
 * @创建时间 2021/2/26
 * @修改人
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
    Logger log = LoggerFactory.getLogger(getClass());


    //绑定Exception
    @ExceptionHandler(Exception.class)
    public <T> DataResult<T> handle(Exception ex) {

        log.error("业务异常e:", ex);
        //异常的日志都打印记录
        log.error(ex.getMessage() + ":"  + ex.getMessage());


        DataResult result = new DataResult(BaseResponseCode.OPERATION_ERRO);
        return result;
    }



    //绑定 BusinessException
    @ExceptionHandler(BusinessException.class)
    public <T> DataResult<T> handler(BusinessException businessException) {
        log.error("业务 BusinessException 异常e:", businessException);
        return new DataResult<>(businessException.getMessageCode(), businessException.getDetailMessage());
    }

    //绑定 AuthorizationException
    @ExceptionHandler(AuthorizationException.class)
    public <T> DataResult<T> handler(AuthorizationException authorizationException) {
        log.error("AuthorizationException 异常e:", authorizationException);

        return new DataResult<>(BaseResponseCode.PERMISSION_DENIED);
    }
    /**
     * 参数校验异常处理类
     * 参数为实体类
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public DataResult handleBindException(MethodArgumentNotValidException ex) {
        FieldError fieldError = ex.getBindingResult().getFieldError();
        log.error("参数校验异常:{}({})", fieldError.getDefaultMessage(), fieldError.getField());
        DataResult result = new DataResult(BaseResponseCode.METHODARGUMENTNOTVALIDEXCEPTION.getCode(), fieldError.getDefaultMessage());
        return result;
    }

    /**
     * 参数校验 非实体请求参数
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(value = ConstraintViolationException.class)
    public DataResult handle(ConstraintViolationException ex) {
        log.error("业务ConstraintViolationException异常e:", ex);
        StringBuilder msg = new StringBuilder();
        Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
        for (ConstraintViolation<?> constraintViolation : constraintViolations) {
            PathImpl pathImpl = (PathImpl) constraintViolation.getPropertyPath();
            String paramName = pathImpl.getLeafNode().getName();
            String message = constraintViolation.getMessage();
            msg.append(message);
        }
        log.error(msg.toString(), ex);
        // 返回参数错误提示
        return new DataResult(BaseResponseCode.METHODARGUMENTNOTVALIDEXCEPTION);
    }


}
