package com.example.struts2.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.ActionContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.StrutsStatics;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 限流拦截器 - 演示拦截器实现横切关注点
 * 
 * 学习点：
 * - 拦截器实现非功能性需求
 * - IP 限流算法
 * - 返回自定义结果
 */
public class RateLimitInterceptor extends AbstractInterceptor {
    
    // IP 请求计数器
    private final Map<String, AtomicLong> ipRequestCounts = new ConcurrentHashMap<>();
    private final Map<String, Long> ipLastAccess = new ConcurrentHashMap<>();
    
    // 每分钟最大请求数
    private long maxRequestsPerMinute = 60;
    
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        // 获取客户端 IP
        String clientIp = getClientIp(invocation);
        
        long currentTime = System.currentTimeMillis();
        Long lastAccess = ipLastAccess.get(clientIp);
        
        // 每分钟重置计数器
        if (lastAccess == null || currentTime - lastAccess > 60000) {
            ipRequestCounts.put(clientIp, new AtomicLong(0));
            ipLastAccess.put(clientIp, currentTime);
        }
        
        AtomicLong count = ipRequestCounts.get(clientIp);
        long currentCount = count.incrementAndGet();
        
        if (currentCount > maxRequestsPerMinute) {
            System.out.println("[RateLimitInterceptor] IP: " + clientIp + 
                " 超过限流阈值: " + currentCount);
            return "rateLimitExceeded";
        }
        
        System.out.println("[RateLimitInterceptor] IP: " + clientIp + 
            " 请求计数: " + currentCount + "/" + maxRequestsPerMinute);
        
        return invocation.invoke();
    }
    
    /**
     * 获取客户端真实 IP
     */
    private String getClientIp(ActionInvocation invocation) {
        ActionContext context = invocation.getInvocationContext();
        HttpServletRequest request = (HttpServletRequest) 
            context.get(StrutsStatics.HTTP_REQUEST);
        
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        
        // 多个代理时取第一个
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0].trim();
        }
        
        return ip;
    }
    
    // Getter/Setter for configuration
    public void setMaxRequestsPerMinute(long max) {
        this.maxRequestsPerMinute = max;
    }
}