

package cn.iocoder.yudao.framework.common.util.ip;

import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;

/**
 * IP帮助工具
 * @author yami
 */
@Slf4j
public class IPHelper {
    private static final String UNKNOWN = "unknown";


    /**
     * 工具类获取浏览器名称及版本
     *
     * @return
     */
    public static String browserName(){
        String userAgent = ServletUtils.getUserAgent();
        UserAgent ua = UserAgent.parseUserAgentString(userAgent);
        Browser browser = ua.getBrowser();
        return browser.getName() + "-" + browser.getVersion(userAgent);
    }

    /**
     * 获取浏览器名称（获取不到IE的信息）
     *
     * @return
     */
    public static String getBrowserName() {
        String browserName = "";
        String userAgent = ServletUtils.getUserAgent();
        if (userAgent == null || userAgent.equals("")) {
            return "";
        }
        if (userAgent.indexOf("MSIE") > 0) {
            browserName = "IE";
        } else if (userAgent.indexOf("FIREFOX") > 0) {
            browserName = "Firefox";
        } else if (userAgent.indexOf("CHROME") > 0) {
            browserName = "Chrome";
        } else if (userAgent.indexOf("SAFARI") > 0) {
            browserName = "Safari";
        } else if (userAgent.indexOf("CAMINO") > 0) {
            browserName = "Camino";
        } else if (userAgent.indexOf("KONQUEROR") > 0) {
            browserName = "Konqueror";
        } else if (userAgent.indexOf("EDGE") > 0) {
            browserName = "Microsoft Edge";
        }
        return browserName;
    }

    /**
     * 工具类获取系统名称
     *
     * @return
     */
    public static String osName(){
        String userAgent = ServletUtils.getUserAgent();
        UserAgent ua = UserAgent.parseUserAgentString(userAgent);
        OperatingSystem os = ua.getOperatingSystem();
        return os.getName();
    }

    /**
     * 获取系统名称
     *
     * @return
     */
    public static String getOSname() {
        String osName = "";
        String userAgent = ServletUtils.getUserAgent();
        if (userAgent.contains("WINDOWS")) {
            if (userAgent.contains("WINDOWS NT 10.0")) {
                osName = "Windows 10";
            } else if (userAgent.contains("WINDOWS NT 6.2")) {
                osName = "Windows 8";
            } else if (userAgent.contains("WINDOWS NT 6.1")) {
                osName = "Windows 7";
            } else if (userAgent.contains("WINDOWS NT 6.0")) {
                osName = "Windows Vista";
            } else if (userAgent.contains("WINDOWS NT 5.2")) {
                osName = "Windows XP";
            } else if (userAgent.contains("WINDOWS NT 5.1")) {
                osName = "Windows XP";
            } else if (userAgent.contains("WINDOWS NT 5.01")) {
                osName = "Windows 2000";
            } else if (userAgent.contains("WINDOWS NT 5.0")) {
                osName = "Windows 2000";
            } else if (userAgent.contains("WINDOWS NT 4.0")) {
                osName = "Windows NT 4.0";
            } else if (userAgent.contains("WINDOWS 98; WIN 9X 4.90")) {
                osName = "Windows ME";
            } else if (userAgent.contains("WINDOWS 98")) {
                osName = "Windows 98";
            } else if (userAgent.contains("WINDOWS 95")) {
                osName = "Windows 95";
            } else if (userAgent.contains("WINDOWS CE")) {
                osName = "Windows CE";
            }
        } else if (userAgent.contains("MAC")){
            osName = "Mac";
        } else if (userAgent.contains("UNIX")){
            osName = "UNIX";
        } else if (userAgent.contains("LINUX")){
            osName = "Linux";
        } else if (userAgent.contains("SUNOS")){
            osName = "SunOS";
        }
        return osName;
    }

    /**
     * 得到用户的真实地址,如果有多个就取第一个
     *
     * @return
     */
    public static String getIpAddr() {
        HttpServletRequest request = ServletUtils.getRequest();
        if (request == null) {
            return null;
        }
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        String[] ips = ip.split(",");
        return ips[0].trim();
    }

    /**
     * 获取IP地址
     *
     * 使用Nginx等反向代理软件， 则不能通过request.getRemoteAddr()获取IP地址
     * 如果使用了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP地址，X-Forwarded-For中第一个非unknown的有效IP字符串，则为真实IP地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = null;

        try {
            ip = request.getHeader("X-Forwarded-For");
            if (StrUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (StrUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (StrUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (StrUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (StrUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        }
        catch (Exception e) {
            log.error("IPHelper ERROR->", e);
        }
        log.info("IPHelper address->{}", ip);

        //使用代理，则获取第一个IP地址
        if(StrUtil.isNotBlank(ip) && ip.length() > 15) {
            if(ip.indexOf(StrUtil.COMMA) > 0) {
                ip = ip.substring(0, ip.indexOf(StrUtil.COMMA));
            }
        }

        return ip;
    }

    /**
     * 获取手机号
     * 如果通信运营商给送的话，一般在Http请求头的x-up-calling-line-id项里
     */
    public static String getMobile(HttpServletRequest request) {
        // WAP网页取得用户的手机号码
        // GPRS
        String mobile = request.getHeader("x-up-calling-line-id");
        if (StrUtil.isBlank(mobile)) {
            // CDMA
            mobile = request.getHeader("x-up-subno");
        }
        if (StrUtil.isBlank(mobile)) {
            mobile = request.getHeader("x-network-info");
        }
        if (StrUtil.isBlank(mobile)) {
            mobile = request.getHeader("deviceid");
        }
        if (StrUtil.isBlank(mobile)) {
            // 有些wap门户站点跳转过来，手机号码由参数mobile传递过来
            mobile = request.getParameter("mobile");
        }
        if (StrUtil.isNotBlank(mobile)) {
            // 某些情况下，手机号码前面会加上中国国际区号86，需要去掉
            if (mobile.length() == 13 && mobile.startsWith("86")) {
                mobile = mobile.substring(2);
            }
            // TODO: 现在，程序可以认为用户身份(手机号码)已经确认，免登录(手机上输入账号密码不太容易)
        }
        return mobile;
    }
}
