package com.lightinit.hsdatashow.common;

import com.lightinit.hsdatashow.json.pojo.PingResultEntity;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by Mr.Yao on 2017/5/22.
 */
public class IPUtils {
    static List<String> regList=new ArrayList<String>();
    static {
        regList.add(":1");
        regList.add("^10\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$");
        regList.add("^172\\.((1[6-9]{1})|(2[0-9]{1})|(3[0-1]{1}))\\.[0-9]{1,3}\\.[0-9]{1,3}$");
        regList.add("^192\\.168\\.[0-9]{1,3}\\.[0-9]{1,3}$");
    }
    public static String getIpAddress(HttpServletRequest request){
        String ip=request.getHeader("HTTP_X_FORWARDED_FOR");
        if (StringUtils.isEmpty(ip)==false) {
            String []ipArray=ip.split(",");
            for (String _ip:ipArray) {
                if(IsPrivateIpAddress(_ip))
                    continue;
                ip=_ip;
                break;
            }
        }
        if (StringUtils.isEmpty(ip)){
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    public static boolean IsPrivateIpAddress(String ip){
        boolean isPrivateIp=false;
        for (String regIp:regList) {
            Pattern pattern=Pattern.compile(regIp);
            Matcher matcher=pattern.matcher(ip);
           if(matcher.matches())
           {
               isPrivateIp=true;
               break;
           }
        }
        return isPrivateIp;
    }

    public static PingResultEntity Ping(String domain,int pingTimes,String ping){
        PingResultEntity entity=new PingResultEntity();
        BufferedReader in = null;
        Runtime r = Runtime.getRuntime();
        // 将要执行的ping命令,此命令是windows格式的命令
        //String pingCommand = "ping " + domain + " -n " + pingTimes;
        String pingCommand=String.format(ping,domain,pingTimes);
        try {
            // 执行命令并获取输出
            System.out.println(pingCommand);
            Process p = r.exec(pingCommand);
            if (p == null) {
                entity.setReachable(false);
            }
            in = new BufferedReader(new InputStreamReader(p.getInputStream()));
            // 逐行检查输出,计算类似出现=23ms TTL=62字样的次数
            int connectedCount = 0;
            String line = null;
            while ((line = in.readLine()) != null) {
                if(StringUtils.isEmpty(entity.getIpAddress())) {
                    String ipLine = getIpAddress(line);
                    if (StringUtils.isEmpty(ipLine) == false)
                        entity.setIpAddress(ipLine);
                }
                connectedCount += getCheckWindowsResult(line)+getCheckLinuxResult(line);
            }
            // 如果出现类似=23ms TTL=62这样的字样,出现的次数=测试次数则返回真
            entity.setReachable(connectedCount>0);
        } catch (Exception ex) {
            ex.printStackTrace();
            // 出现异常则返回假
            entity.setReachable(false);
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return entity;
    }

    //若line含有=18ms TTL=16字样,说明已经ping通,返回1,否則返回0.
    private static int getCheckWindowsResult(String line) {
        // System.out.println("控制台输出的结果为:"+line);
        Pattern pattern = Pattern.compile("(\\d+ms)(\\s+)(TTL=\\d+)",Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(line);
        while (matcher.find()) {
            return 1;
        }
        return 0;
    }
    //若line含有=18ms TTL=16字样,说明已经ping通,返回1,否則返回0.
    private static int getCheckLinuxResult(String line) {
        // 64 bytes from 150.138.158.3: icmp_seq=1 ttl=43 time=61.8 ms
        Pattern pattern = Pattern.compile("(icmp_seq=\\d+\\s+ttl=\\d+\\s+time=[0-9]{1,}([.][0-9]*)*\\s*ms)",Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(line);
        while (matcher.find()) {
            return 1;
        }
        return 0;
    }
    public static String getIpAddress(String line) {
        // System.out.println("控制台输出的结果为:"+line);
        Pattern pattern = Pattern.compile("(([1-9]{1})([0-9]{0,2})\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})",Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(line);
        while (matcher.find()) {
            return matcher.group();
        }
        return "";
    }
    public static String getDomain(String line) {
        // System.out.println("控制台输出的结果为:"+line);
        Pattern pattern = Pattern.compile("(([a-zA-Z0-9][a-zA-Z0-9-_]+\\.)+[a-zA-Z0-9-_][^ ]*)",Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(line);
        while (matcher.find()) {
            return matcher.group();
        }
        return "";
    }

    public static boolean checkIpAddress(String targetIp,String rightIp) {
        if(StringUtils.isEmpty(targetIp) || StringUtils.isEmpty(rightIp))
            return false;
        String []rightIps=rightIp.split(";");
        for (String ip:rightIps) {
            if(targetIp.trim().equalsIgnoreCase(ip.trim()))
                return true;
        }
        return false;
    }
}
