package com.ningdatech.kqapi.common.handler;

import com.ningdatech.kqapi.common.model.ApiResponse;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * <p>
 * GlobalResponseHandler
 * </p>
 *
 * @author WendyYang
 * @since 15:16 2024/4/20
 */
@RestControllerAdvice(basePackages = {
        "com.ningdatech.kqapi.admin.controller",
        "com.ningdatech.kqapi.user.controller",
        "com.ningdatech.kqapi.security.controller",
        "com.ningdatech.kqapi.zzsfw.controller",
        "com.ningdatech.kqapi.scheduler.controller",
        "com.ningdatech.kqapi.irs.controller"
})
public class GlobalResponseHandler implements ResponseBodyAdvice<Object> {

    private static final String SWAGGER_CLASS_PREFIX = "springfox.documentation";

    @Override
    public boolean supports(MethodParameter methodParameter,
                            Class<? extends HttpMessageConverter<?>> aClass) {
        return filter(methodParameter);
    }

    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter,
                                  MediaType mediaType,
                                  Class<? extends HttpMessageConverter<?>> aClass,
                                  ServerHttpRequest serverHttpRequest,
                                  ServerHttpResponse serverHttpResponse) {
        return ApiResponse.ofSuccess(o);
    }

    private Boolean filter(MethodParameter methodParameter) {
        Class<?> declaringClass = methodParameter.getDeclaringClass();
        // swagger中的所有返回不进行统一封装
        if (declaringClass.getName().contains(SWAGGER_CLASS_PREFIX)) {
            return false;
        }
        if (methodParameter.hasMethodAnnotation(ExceptionHandler.class)) {
            return false;
        }
        // 如果本身就是使用ApiResponse返回，则不需要进行格式化
        return !methodParameter.getParameterType().equals(ApiResponse.class);
    }
}
