#!/bin/bash

# 定义颜色输出（增强可读性）
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # 重置颜色

# 配置项
PING_COUNT=20          # 每个节点ping的次数
MAX_PARALLEL=100        # 最大并行进程数（可根据服务器性能调整）
RESULT_FILE=$(mktemp)  # 临时存储测试结果
LOCK_FILE=$(mktemp)    # 并发控制锁文件

# 节点数据定义（格式：地区|城市|IP）
declare -a NODES=(
    "North America|Ashburn, VA, US|216.66.22.2"
    "North America|Calgary, AB, CA|216.218.200.58"
    "North America|Chicago, IL, US|184.105.253.14"
    "North America|Dallas, TX, US|184.105.253.10"
    "North America|Denver, CO, US|184.105.250.46"
    "North America|Fremont, CA, US|72.52.104.74"
    "North America|Fremont, CA, US|64.62.134.130"
    "North America|Honolulu, HI, US|64.71.156.86"
    "North America|Kansas City, MO, US|216.66.77.230"
    "North America|Los Angeles, CA, US|66.220.18.42"
    "North America|Miami, FL, US|209.51.161.58"
    "North America|New York, NY, US|209.51.161.14"
    "North America|Phoenix, AZ, US|66.220.7.82"
    "North America|Seattle, WA, US|216.218.226.238"
    "North America|Toronto, ON, CA|216.66.38.58"
    "North America|Winnipeg, MB, CA|184.105.255.26"
    "Europe|Amsterdam, NL|216.66.84.46"
    "Europe|Berlin, DE|216.66.86.114"
    "Europe|Budapest, HU|216.66.87.14"
    "Europe|Frankfurt, DE|216.66.80.30"
    "Europe|Lisbon, PT|216.66.87.102"
    "Europe|London, UK|216.66.80.26"
    "Europe|London, UK|216.66.88.98"
    "Europe|Paris, FR|216.66.84.42"
    "Europe|Prague, CZ|216.66.86.122"
    "Europe|Stockholm, SE|216.66.80.90"
    "Europe|Warsaw, PL|216.66.80.162"
    "Europe|Zurich, CH|216.66.80.98"
    "Asia|Hong Kong, HK|216.218.221.6"
    "Asia|Singapore, SG|216.218.221.42"
    "Asia|Tokyo, JP|74.82.46.6"
    "Africa|Djibouti City, DJ|216.66.87.98"
    "Africa|Johannesburg, ZA|216.66.87.134"
    "South America|Bogota, CO|216.66.64.154"
    "Oceania|Sydney, NSW, AU|216.218.142.50"
    "Middle East|Dubai, AE|216.66.90.30"
)

# 测试单个节点的函数（后台执行）
test_node() {
    local region="$1"
    local city="$2"
    local ip="$3"
    local temp_log=$(mktemp)  # 单个节点的ping日志

    # 执行ping测试（兼容Linux和macOS）
    if [[ "$(uname)" == "Darwin" ]]; then
        # macOS: -c 次数，-q 安静模式，-W 超时（秒）
        ping -c ${PING_COUNT} -q -W 2 ${ip} > "${temp_log}" 2>&1
    else
        # Linux: -c 次数，-q 安静模式，-W 超时（秒）
        ping -c ${PING_COUNT} -q -W 2 ${ip} > "${temp_log}" 2>&1
    fi

    # 解析测试结果
    if [[ $? -ne 0 ]]; then
        # 节点无法访问
        echo "${region}|${city}|${ip}|100.00%|0.00|超时" >> "${RESULT_FILE}"
        rm -f "${temp_log}"
        return
    fi

    # 提取丢包率和平均延迟（兼容Linux/macOS）
    if [[ "$(uname)" == "Darwin" ]]; then
        packet_loss=$(grep -Eo '[0-9.]+% packet loss' "${temp_log}" | cut -d% -f1)
        avg_rtt=$(grep -Eo 'avg = [0-9.]+' "${temp_log}" | awk '{print $3}')
    else
        packet_loss=$(grep -Eo '[0-9.]+% packet loss' "${temp_log}" | cut -d% -f1)
        avg_rtt=$(grep -Eo 'rtt min/avg/max/mdev = [0-9./]+' "${temp_log}" | awk -F'/' '{print $5}')
    fi

    # 处理空值
    [[ -z "${packet_loss}" ]] && packet_loss="0.00"
    [[ -z "${avg_rtt}" ]] && avg_rtt="0.00"

    # 写入结果文件
    echo "${region}|${city}|${ip}|${packet_loss}%|${avg_rtt}|正常" >> "${RESULT_FILE}"

    # 清理临时日志
    rm -f "${temp_log}"

    # 输出完成提示（可选，后台输出可能乱序）
    echo -e "${BLUE}[完成] ${city} (${ip}) - 丢包率: ${packet_loss}%, 平均延迟: ${avg_rtt} ms${NC}"
}

# 并发控制函数：等待空闲进程槽位
wait_for_slot() {
    while true; do
        local current_parallel=$(pgrep -P $$ | wc -l)
        if [[ ${current_parallel} -lt ${MAX_PARALLEL} ]]; then
            break
        fi
        sleep 0.1
    done
}

# 主程序：启动并行测试
echo -e "${YELLOW}==================== 开始并行测试所有节点 ====================${NC}"
echo -e "并行进程数：${MAX_PARALLEL} | 每个节点Ping次数：${PING_COUNT}\n${NC}"

for node in "${NODES[@]}"; do
    # 等待空闲槽位
    wait_for_slot

    # 分割节点数据
    IFS='|' read -r region city ip <<< "$node"
    echo -e "${YELLOW}[启动] 测试节点：${city} (${ip})${NC}"

    # 后台执行节点测试
    test_node "${region}" "${city}" "${ip}" &
done

# 等待所有后台进程完成
echo -e "\n${YELLOW}等待所有节点测试完成...${NC}"
wait

# 处理测试结果
echo -e "\n${YELLOW}==================== 测试结果汇总 ====================${NC}"

# 按丢包率升序、平均延迟升序排序
SORTED_RESULT=$(sort -t'|' -k4,4n -k5,5n "${RESULT_FILE}")

# 提取最优节点
BEST_NODE=$(echo "${SORTED_RESULT}" | head -n1)
IFS='|' read -r best_region best_city best_ip best_loss best_avg best_status <<< "${BEST_NODE}"

# 输出最优节点
echo -e "${GREEN}★ 最优节点 ★${NC}"
echo "地区：${best_region}"
echo "城市：${best_city}"
echo "IP地址：${best_ip}"
echo "丢包率：${best_loss}"
echo "平均延迟：${best_avg} ms"
echo "状态：${best_status}"

# 输出所有节点的排序结果（可选）
echo -e "\n${YELLOW}所有节点测试结果（按最优排序）：${NC}"
echo -e "地区\t\t城市\t\tIP地址\t\t丢包率\t\t平均延迟(ms)\t状态"
echo "${SORTED_RESULT}" | while IFS='|' read -r region city ip loss avg status; do
    printf "%-15s %-20s %-18s %-10s %-15s %-5s\n" "${region}" "${city}" "${ip}" "${loss}" "${avg}" "${status}"
done

# 清理临时文件
rm -f "${RESULT_FILE}" "${LOCK_FILE}"

echo -e "\n${GREEN}✅ 所有节点测试完成！${NC}"