/*
 * 文 件 名:  PingUtils
 * 版    权:  华设设计集团股份有限公司
 * 描    述:  <描述>
 * 修 改 人:  lvwenbin
 * 修改时间:  2025/9/18
 * 跟踪单号:  <跟踪单号>
 * 修改单号:  <修改单号>
 * 修改内容:  <修改内容>
 */
package com.ruoyi.ems.util;

import lombok.extern.slf4j.Slf4j;

import java.net.InetAddress;
import java.util.concurrent.TimeUnit;

/**
 * Ping工具
 * <功能详细描述>
 *
 * @author lvwenbin
 * @version [版本号, 2025/9/18]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Slf4j
public abstract class PingUtils {
    /**
     * 从URL中提取IP地址
     *
     * @param url 完整URL，如 http://172.17.50.186:80
     * @return IP地址
     */
    public static String extractIpFromUrl(String url) {
        try {
            // 去除协议前缀
            String temp = url;
            if (url.startsWith("http://")) {
                temp = url.substring(7);
            }
            else if (url.startsWith("https://")) {
                temp = url.substring(8);
            }

            // 提取IP部分（去除端口）
            int colonIndex = temp.indexOf(':');
            int slashIndex = temp.indexOf('/');

            if (colonIndex > 0) {
                return temp.substring(0, colonIndex);
            }
            else if (slashIndex > 0) {
                return temp.substring(0, slashIndex);
            }
            else {
                return temp;
            }
        }
        catch (Exception e) {
            log.error("提取IP地址失败: {}", url, e);
            return null;
        }
    }

    /**
     * Ping指定主机
     *
     * @param host    IP地址或主机名
     * @param timeout 超时时间（毫秒）
     * @return true=可达，false=不可达
     */
    public static boolean pingHost(String host, int timeout) {
        try {
            // 方式1：使用Java内置的InetAddress.isReachable
            InetAddress address = InetAddress.getByName(host);
            boolean reachable = address.isReachable(timeout);

            // 方式2：如果需要更准确的ping，可以使用系统命令
            if (!reachable && isWindows()) {
                reachable = pingByCommand(host, timeout);
            }

            return reachable;
        }
        catch (Exception e) {
            log.error("Ping主机失败: {}", host, e);
            return false;
        }
    }

    /**
     * 通过系统命令执行ping
     *
     * @param host    IP地址
     * @param timeout 超时时间（毫秒）
     * @return true=可达，false=不可达
     */
    public static boolean pingByCommand(String host, int timeout) {
        try {
            String command;
            if (isWindows()) {
                // Windows: ping -n 1 -w timeout host
                command = String.format("ping -n 1 -w %d %s", timeout, host);
            }
            else {
                // Linux/Unix: ping -c 1 -W timeout host
                command = String.format("ping -c 1 -W %d %s", timeout / 1000, host);
            }

            Process process = Runtime.getRuntime().exec(command);
            boolean finished = process.waitFor(timeout + 1000, TimeUnit.MILLISECONDS);

            if (!finished) {
                process.destroyForcibly();
                return false;
            }

            return process.exitValue() == 0;
        }
        catch (Exception e) {
            log.error("执行ping命令失败: {}", host, e);
            return false;
        }
    }

    /**
     * 判断是否Windows系统
     */
    private static boolean isWindows() {
        String os = System.getProperty("os.name").toLowerCase();
        return os.contains("win");
    }
}