package com.sikey.wa04.common.utils;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.net.NetUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.experimental.UtilityClass;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


/**
 * @Author: qin
 * @Date: 2025/4/30
 * @Description: ip
 */
@UtilityClass
public class IpUtil {
    // 可信代理 CIDR 列表（根据实际网络拓扑配置）
    private static final List<String> TRUSTED_PROXY_CIDRS = new ArrayList<String>() {{
        add("192.168.1.0/24"); // 内部网络
        add("10.0.0.0/8");     // 私有网络
    }};

    /**
     * 获取客户端真实 IP（自动处理 X-Forwarded-For 及代理验证）
     */
    public static String getClientIP(HttpServletRequest request) {
        // 1. 从 X-Forwarded-For 头部解析代理链
        String xff = request.getHeader("X-Forwarded-For");
        if (xff != null && !xff.isEmpty()) {
            List<String> ips = parseProxyChain(xff);
            // 反向遍历代理链，寻找第一个不可信 IP
            for (int i = ips.size() - 1; i >= 0; i--) {
                String ip = ips.get(i).trim();
                if (isValidIp(ip) && !isTrustedProxy(ip)) {
                    return ip;
                }
            }
        }

        // 2. 直接连接的客户端 IP（无代理或代理链全可信）
        return request.getRemoteAddr();
    }

    /**
     * 解析 X-Forwarded-For 头部为 IP 列表
     */
    private static List<String> parseProxyChain(String xff) {
        List<String> ips = new ArrayList<>();
        Collections.addAll(ips, xff.split(","));
        return ips;
    }

    /**
     * 验证 IP 是否有效
     */
    private static boolean isValidIp(String ip) {
        return Validator.isIpv4(ip) || Validator.isIpv6(ip);
    }

    /**
     * 判断 IP 是否属于可信代理
     */
    private static boolean isTrustedProxy(String ip) {
        return TRUSTED_PROXY_CIDRS.stream()
                .anyMatch(cidr -> NetUtil.isInRange(ip, cidr));
    }
}
