package com.wecloud.utils;

import cn.hutool.http.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

/**
 * 获取公网ip
 */
@Component
@Slf4j
public class GetIpUtils {

    private static final String LOCAL = "local";
    private static final String AWS = "aws";
    private static final String HUAWEI_CLOUD = "huawei";

    /**
     * 内网ip
     */
    private static String lAN_IP = null;

    /**
     * 公网ip
     */
    private static String PUBLIC_IP = null;


    /**
     * 服务器运营商local,aws,huawei
     */
    @Value("${load-blance.server-type}")
    private String serverType;

    /**
     * 排除无效的mac地址
     */
    private final static byte[][] INVALID_MACS = {
            {0x00, 0x05, 0x69},             // VMWare
            {0x00, 0x1C, 0x14},             // VMWare
            {0x00, 0x0C, 0x29},             // VMWare
            {0x00, 0x50, 0x56},             // VMWare
            {0x08, 0x00, 0x27},             // Virtualbox
            {0x0A, 0x00, 0x27},             // Virtualbox
            {0x00, 0x03, (byte) 0xFF},       // Virtual-PC
            {0x00, 0x15, 0x5D}              // Hyper-V
    };

    /**
     * 判断是否为虚拟mac地址
     *
     * @param mac
     * @return
     */
    private static boolean isVmMac(byte[] mac) {
        if (null == mac) {
            return false;
        }

        for (byte[] invalid : INVALID_MACS) {
            if (invalid[0] == mac[0] && invalid[1] == mac[1] && invalid[2] == mac[2]) {
                return true;
            }
        }

        return false;
    }

    /**
     * 获取本机地址
     */
    private static String getLocalIpAddress() {
        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface ni = networkInterfaces.nextElement();

                /*
                    排除docker虚拟网卡
                 */
                String docker0 = "docker0";
                if (ni.getName().equals(docker0)) {
                    continue;
                }
                if (!ni.isUp() || ni.isLoopback() || ni.isVirtual()) {
                    continue;
                }

                if (isVmMac(ni.getHardwareAddress())) {
                    continue;
                }
                Enumeration<InetAddress> inetAddresses = ni.getInetAddresses();
                while (inetAddresses.hasMoreElements()) {
                    InetAddress inetAddress = inetAddresses.nextElement();
                    if (inetAddress.isLinkLocalAddress()) {
                        continue;
                    }
                    return inetAddress.getHostAddress();
                }
            }
        } catch (SocketException e) {
            log.info("获取本机IP地址失败。" + e);


        }
        return StringUtils.EMPTY;
    }

    /**
     * 内网ip
     *
     * @return
     */
    public static String getlanIp() {

        if (lAN_IP == null) {
            synchronized (GetIpUtils.class) {
                if(lAN_IP == null) {
                    lAN_IP = getLocalIpAddress();
                }
            }
        }

        return lAN_IP;
    }

    /**
     * 公网ip
     */
    public String getPublicIp() {

        if (PUBLIC_IP == null) {
            switch (serverType) {
                case LOCAL:
                    PUBLIC_IP = getlanIp();
                    break;
                case AWS:
                    PUBLIC_IP = HttpUtil.get("http://instance-data/latest/meta-data/public-ipv4", 30);
                    break;
                case HUAWEI_CLOUD:
                    PUBLIC_IP = HttpUtil.get("http://169.254.169.254/latest/meta-data/public-ipv4", 30);
                    break;
                default:
            }
        }
        return PUBLIC_IP;
    }

}
