package cn.quantgroup.xyqb.util;

import cn.quantgroup.tech.util.TechEnvironment;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Objects;
import java.util.Set;

/**
 * IP地址工具类
 *
 * @author renwc
 * @date 2017-12-01
 */
public class IpUtil {
    /**
     * IP白名单
     * <p>
     * 192.168.3.0/24 - 公有云测试业务
     * 192.168.4.0/24 - 公有云测试业务
     * 172.16.0.0/16 - 公有云正式业务
     * 172.18.0.0/16 - 腾讯云
     * 172.20.0.0/16 - 3B私有云
     * 172.30.0.0/16 - 3C私有云
     * 172.41.0.0/16 - 3B,docker内网
     */
    private static final Set<String> WHITE_ADDRESS = Sets.newHashSet();
    private static final String LOCAL_ADDRESS = "127.0.0.1";
    /** 入口服务器IP */
    public static final String IO_IP = "139.198.";

    static {
        String[] ips = {"10.", "172.", "192.168.3.", "192.168.4."};
        WHITE_ADDRESS.addAll(Arrays.asList(ips));
        //系统环境
        if (!TechEnvironment.isPro()) {
            WHITE_ADDRESS.add("192.168.");
            WHITE_ADDRESS.add("172.17.");
            WHITE_ADDRESS.add("10.");
            //劲松的测试环境
            WHITE_ADDRESS.add("54.223.247.69");
            WHITE_ADDRESS.add(LOCAL_ADDRESS);
        }
    }

    /**
     * 判断是否为白名单IP
     *
     * @param ipv4
     * @return
     */
    public static final boolean whiteOf(String ipv4) {
        if (ValidationUtil.validateIpv4(ipv4)) {
            for (String ipField : WHITE_ADDRESS) {
                if (ipv4.startsWith(ipField)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 打印IP
     *
     * @param logger  - 日志记录器
     * @param request - 真实HttpServletRequest请求
     */
    public static final void logIp(Logger logger, HttpServletRequest request) {
        if (Objects.isNull(request)) {
            return;
        }
        String remoteAddr = request.getRemoteAddr();
        String xRealIp = request.getHeader("x-real-ip");
        String xOriginalClientIp = request.getHeader("x-original-client-ip");
        logger.info("Test ips:[client={}, old={}, new={}]", remoteAddr, xRealIp, xOriginalClientIp);
    }

    /**
     * 获取请求客户端的真实ip地址
     *
     * @param request
     * @return
     */
    public static String getRemoteIP(HttpServletRequest request) {
        Objects.requireNonNull(request, "无效请求");
        String ip = request.getHeader("x-original-client-ip");
        if (ValidationUtil.validateIpv4(ip) && !Objects.equals(LOCAL_ADDRESS, ip)) {
            return ip;
        }

        // Todo - 以下为老代码，保留容错
        ip = request.getHeader("x-real-ip");
        if (StringUtils.isEmpty(ip)) {
            ip = request.getRemoteAddr();
        }
        //过滤反向代理的ip
        String[] stemps = ip.split(",");
        if (stemps != null && stemps.length > 0) {
            //得到第一个IP，即客户端真实IP
            ip = stemps[0];
        }
        ip = ip.trim();
        int twentyThree = 23;
        if (ip.length() > twentyThree) {
            ip = ip.substring(0, twentyThree);
        }
        return ip;
    }
}
