package com.changhu.support.interceptor;

import cn.hutool.core.collection.ConcurrentHashSet;
import com.changhu.common.annotation.JsonBody;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Set;

/**
 * author: luozhun
 * desc: 方法或者类上是否添加JsonBody注解，如果有 需要进行标记
 * createTime: 2023/8/18 10:50
 */
@Slf4j
public class JsonBodyInterceptor implements HandlerInterceptor {

    public static final String RESPONSE_ATTRIBUTE = "ResponseAttribute";

    private static final Set<String> cache = new ConcurrentHashSet<>();

    @Override
    public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) {
        if (handler instanceof HandlerMethod handlerMethod) {
            //com.xxx.xxController#methodName(params1 , params2)
            String methodDescription = handlerMethod.toString();
            //如果缓存有标识 则直接返回
            if (cache.contains(methodDescription)) {
                request.setAttribute(RESPONSE_ATTRIBUTE, true);
                return true;
            }

            boolean b = false;

            JsonBody clazzJsonBody = handlerMethod.getBeanType().getAnnotation(JsonBody.class);
            JsonBody methodJsonBody = handlerMethod.getMethodAnnotation(JsonBody.class);
            if (clazzJsonBody != null) {
                //默认是当前controller下的所有方法都以JsonResult输出 为了兼容部分不需要包装的方法 需要判断方法上是否有JsonBody(value=false)
                if (methodJsonBody == null) {
                    b = true;
                } else if (methodJsonBody.value()) {
                    b = true;
                }
            } else {
                if (methodJsonBody != null && methodJsonBody.value()) {
                    b = true;
                }
            }

            if (b) {
                //添加Attribute，便于后续JsonBodyAdvice处理
                request.setAttribute(RESPONSE_ATTRIBUTE, true);
                //缓存
                cache.add(methodDescription);
            }
        }
        return true;
    }
}
