package com.ltgk.common.config;

import org.apache.coyote.http11.Http11NioProtocol;
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.async.TimeoutCallableProcessingInterceptor;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Author: wan kun
 * @Description: TODO
 * @Date: 2025/7/9 9:05
 * @Version: 1.0
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(requestTimeoutInterceptor())
                .addPathPatterns("/**");  // 拦截所有请求
    }

    @Bean
    public RequestTimeoutInterceptor requestTimeoutInterceptor() {
        return new RequestTimeoutInterceptor(60000);  // 30秒超时
    }

    static class RequestTimeoutInterceptor extends HandlerInterceptorAdapter {
        private final long timeout;

        public RequestTimeoutInterceptor(long timeout) {
            this.timeout = timeout;
        }

        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
            request.setAttribute("requestStartTime", System.currentTimeMillis());
            return true;
        }

        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
            long startTime = (long) request.getAttribute("requestStartTime");
            long processingTime = System.currentTimeMillis() - startTime;

            if (processingTime > timeout) {
                // 记录超时请求
                System.out.println("请求超时: " + request.getRequestURI() + ", 耗时: " + processingTime + "ms");
            }
        }
    }

    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        // 设置异步请求超时时间为5分钟
        configurer.setDefaultTimeout(300000L);
        configurer.registerCallableInterceptors(timeoutCallableInterceptor());
    }

    @Bean
    public TimeoutCallableProcessingInterceptor timeoutCallableInterceptor() {
        return new TimeoutCallableProcessingInterceptor();
    }

    // 如果使用嵌入式Tomcat，增加连接超时配置
    @Bean
    public TomcatProtocolHandlerCustomizer<Http11NioProtocol> protocolHandlerCustomizer() {
        return protocol -> {
            // 设置连接超时时间（毫秒）
            protocol.setConnectionTimeout(300000);

            // 设置 keep-alive 超时时间（毫秒）
            protocol.setKeepAliveTimeout(300000);

            // 设置最大 keep-alive 请求数
            protocol.setMaxKeepAliveRequests(100);
        };
    }
}
