package com.beagle.base.common.exception;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException;
import org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import com.beagle.base.bean.vo.resp.BaseResponse;
import com.beagle.base.common.contant.CodeEnum;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartException;

import java.util.stream.Collectors;
/**
 * @author wuwanli
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     * @param exception 自定义异常
     * @return BaseResponse
     */
    @ExceptionHandler(value = BeagleException.class)
    public BaseResponse beagleExceptionHandler(BeagleException exception) {
        log.error("GlobalExceptionHandler.beagleExceptionHandler", exception);
        BaseResponse baseResponse = BaseResponse.fail();
        if (!StringUtils.isBlank(exception.getErrorCode())) {
            baseResponse.setCode(exception.getErrorCode());
            baseResponse.setDesc(exception.getErrorMsg());
        }
        return baseResponse;
    }
    @ExceptionHandler(value = MultipartException.class)
    public BaseResponse MultipartExceptionHandler(MaxUploadSizeExceededException exception) {
        log.error("GlobalExceptionHandler.MultipartException", exception);
        String msg = "";
        BaseResponse baseResponse = BaseResponse.fail();
        if (exception.getCause().getCause() instanceof FileSizeLimitExceededException) {
            log.error(exception.getMessage());
            baseResponse = BaseResponse.fail(CodeEnum.EXCEED_FILE_MAX);
        }else if (exception.getCause().getCause() instanceof SizeLimitExceededException) {
            log.error(exception.getMessage());
            baseResponse = BaseResponse.fail(CodeEnum.EXCEED_TOTAL_FILE_MAX);
        }
        return baseResponse;
    }



    /**
     * @param exception 系统异常
     * @return BaseResponse
     */
    @ExceptionHandler(value = Exception.class)
    public BaseResponse exceptionHandler(Exception exception) {
        log.error("GlobalExceptionHandler.exceptionHandler", exception);
        return BaseResponse.fail();
    }

    /**
     * @param exception 不支持 HTTP 方法
     * @return BaseResponse
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public BaseResponse httpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException exception) {
        log.error("GlobalExceptionHandler.httpRequestMethodNotSupportedException", exception);
        return BaseResponse.fail(CodeEnum.HTTP_METHOD_NOT_SUPPORTED);
    }

    /**
     * @param exception 参数校验失败
     * @return BaseResponse
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public BaseResponse methodArgumentNotValidException(MethodArgumentNotValidException exception) {
        log.error("GlobalExceptionHandler.methodArgumentNotValidException", exception);
        BindingResult bindingResult = exception.getBindingResult();
        if (bindingResult.hasErrors()) {
            String errorInfo = bindingResult.getAllErrors().stream().map(ObjectError::getDefaultMessage)
                .collect(Collectors.joining(";"));
            return BaseResponse.fail(CodeEnum.ARGUMENT_VALID_ERROR.getCode(), errorInfo);
        }
        return BaseResponse.fail(CodeEnum.ARGUMENT_VALID_ERROR);
    }

    /**
     * @param exception 参数类型错误
     * @return BaseResponse
     */
    @ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
    public BaseResponse methodArgumentTypeMismatchException(MethodArgumentTypeMismatchException exception) {
        log.error("GlobalExceptionHandler.methodArgumentTypeMismatchException", exception);
        return BaseResponse.fail(CodeEnum.ARGUMENT_TYPE_ERROR);
    }
}
