#!/bin/bash

# ========================================================
# Debian 镜像源 TCP 80 端口延迟测试 (分流选择版)
# ========================================================

TCPING_EXE="tcping"

# ---------- 安装检测与全平台自动修复 ----------
if ! command -v tcping &>/dev/null && [ ! -f "./tcping" ]; then
    echo "未检测到系统 tcping，正在尝试智能安装..."
    if [ "$(uname -s)" = "Darwin" ]; then
        command -v brew &>/dev/null && brew install tcping
    else
        if command -v apt-get &>/dev/null; then
            sudo apt-get update -y && sudo apt-get install -y tcping 2>/dev/null
        elif command -v yum &>/dev/null; then
            sudo yum install -y tcping 2>/dev/null
        fi
        
        if ! command -v tcping &>/dev/null; then
            echo "提示: 官方软件源未找到 tcping，正在从 GitHub 下载独立二进制版..."
            ARCH=$(uname -m)
            URL="https://github.com/cloverstd/tcping/releases/download/v0.1.1/tcping-linux-amd64-v0.1.1.tar.gz"
            if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
                URL="https://github.com/cloverstd/tcping/releases/download/v0.1.1/tcping-linux-arm64-v0.1.1.tar.gz"
            fi
            
            if command -v curl &>/dev/null; then
                curl -L "$URL" -o tcping.tar.gz
            elif command -v wget &>/dev/null; then
                wget -O tcping.tar.gz "$URL"
            fi
            
            if [ -f "tcping.tar.gz" ]; then
                tar -zxf tcping.tar.gz
                mv tcping-linux-* tcping 2>/dev/null
                chmod +x tcping
                rm -f tcping.tar.gz
                echo "独立版 tcping 下载并配置成功！"
            fi
        fi
    fi
fi

if command -v tcping &>/dev/null; then
    TCPING_EXE="tcping"
elif [ -f "./tcping" ]; then
    TCPING_EXE="./tcping"
fi

# ---------- 探测 tcping 支持的限次参数 ----------
TCPING_STYLE="unknown"
TCPING_CMD=""
_help=$( { "$TCPING_EXE" --help 2>&1; "$TCPING_EXE" -h 2>&1; } | head -60 )

if echo "$_help" | grep -qE '\-c[[:space:],]|--count'; then
    TCPING_CMD="$TCPING_EXE -c 3"
    TCPING_STYLE="linux"
elif echo "$_help" | grep -qE '\-n[[:space:],]|--number|-t[[:space:]]'; then
    TCPING_CMD="$TCPING_EXE -n 3"
    TCPING_STYLE="win"
else
    TCPING_CMD=""
    TCPING_STYLE="fallback"
fi

# ---------- 颜色 ----------
GREEN='\033[0;32m'; YELLOW='\033[0;33m'; PURPLE='\033[0;35m'; RED='\033[0;31m'; NC='\033[0m'

# ========================================================
# 交互菜单选择
# ========================================================
echo "========================================================="
echo "          Debian 镜像源延迟测试工具 (tcping)"
echo "========================================================="
echo "  1. 中国大陆（包含各大高校、大厂公有云、本地节点）"
echo "  2. 海外国际（包含亚太优化、全球大厂、欧美顶尖高校）"
echo "========================================================="
read -p "请选择需要测试的范围 [1-2] (默认 1): " CHOICE
CHOICE=${CHOICE:-1}

# ---------- 声明临时使用数组 ----------
declare -A domains
declare -A names

if [ "$CHOICE" = "2" ]; then
    # ---------- 海外 (Overseas) 镜像数据 ----------
    domains=(
        ["xtom_hk"]="mirrors.xtom.hk"
        ["xtom_jp"]="mirrors.xtom.jp"
        ["xtom_sg"]="mirrors.xtom.sg"
        ["jaist"]="ftp.jaist.ac.jp"
        ["nchc"]="free.nchc.org.tw"
        ["kernel"]="mirrors.kernel.org"
        ["leaseweb_nl"]="mirror.nl.leaseweb.net"
        ["mit"]="mirrors.mit.edu"
        ["deb_org"]="deb.debian.org"
    )
    names=(
        ["xtom_hk"]="香港 xTom 镜像源"
        ["xtom_jp"]="日本 xTom 镜像源"
        ["xtom_sg"]="新加坡 xTom 镜像源"
        ["jaist"]="日本 JAIST 杰斯特源"
        ["nchc"]="台湾 NCHC 高速网络中心"
        ["kernel"]="美国 Kernel.org 内核站"
        ["leaseweb_nl"]="荷兰 Leaseweb 核心源"
        ["mit"]="美国麻省理工 MIT 源"
        ["deb_org"]="Debian 全球官方主源"
    )
    TARGET_NAME="海外国际"
else
    # ---------- 中国大陆 (Mainland China) 镜像数据 ----------
    domains=(
        ["ftp_cn"]="ftp.cn.debian.org"
        ["163"]="mirrors.163.com"
        ["ustc"]="mirrors.ustc.edu.cn"
        ["lzu"]="mirror.lzu.edu.cn"
        ["bfsu"]="mirrors.bfsu.edu.cn"
        ["nju"]="mirror.nju.edu.cn"
        ["sjtu"]="mirror.sjtu.edu.cn"
        ["nyist"]="mirror.nyist.edu.cn"
        ["zju"]="mirrors.zju.edu.cn"
        ["jlu"]="mirrors.jlu.edu.cn"
        ["tsinghua"]="mirrors.tuna.tsinghua.edu.cn"
        ["archive"]="debian-archive.trafficmanager.net"
        ["aliyun"]="mirrors.aliyun.com"
        ["tencent"]="mirrors.cloud.tencent.com"
        ["huawei"]="mirrors.huaweicloud.com"
        ["volces"]="mirrors.volces.com"
        ["pku"]="mirrors.pku.edu.cn"
        ["xjtu"]="mirrors.xjtu.edu.cn"
        ["hust"]="mirrors.hust.edu.cn"
        ["cqu"]="mirrors.cqu.edu.cn"
    )
    names=(
        ["ftp_cn"]="Debian 中国主源"
        ["163"]="网易 163 镜像源"
        ["ustc"]="中国科学技术大学源"
        ["lzu"]="兰州大学镜像源"
        ["bfsu"]="北京外国语大学源"
        ["nju"]="南京大学镜像源"
        ["sjtu"]="上海交通大学源"
        ["nyist"]="南阳理工学院源"
        ["zju"]="浙江大学镜像源"
        ["jlu"]="吉林大学镜像源"
        ["tsinghua"]="清华大学 TUNA 源"
        ["archive"]="微软云 Debian 归档源"
        ["aliyun"]="阿里云开源镜像站"
        ["tencent"]="腾讯云开源镜像站"
        ["huawei"]="华为云开源镜像站"
        ["volces"]="火山引擎(字节)源"
        ["pku"]="北京大学开源镜像站"
        ["xjtu"]="西安交通大学镜像站"
        ["hust"]="华中科技大学镜像站"
        ["cqu"]="重庆大学开源镜像站"
    )
    TARGET_NAME="中国大陆"
fi

RESULT_FILE=$(mktemp 2>/dev/null || mktemp -t 'debian_mirrors_tcping')
PROBE_COUNT=3
NC_TIMEOUT=4      # nc 兜底时的超时秒数

# ========================================================
# 从 tcping 原始输出中提取平均延迟（ms，纯数字）
# ========================================================
_extract_avg() {
    local raw="$1"
    local avg=""

    avg=$(echo "$raw" | grep -iE 'min/avg/max' \
          | grep -oE '[0-9]+\.?[0-9]*/[0-9]+\.?[0-9]*/[0-9]+\.?[0-9]*' \
          | awk -F'/' '{print $2}' | head -n1)
    [ -n "$avg" ] && { echo "$avg"; return; }

    avg=$(echo "$raw" | grep -iE 'average\s*=\s*[0-9]|avg\s*=\s*[0-9]' \
          | grep -oE '(average|avg)\s*=\s*[0-9]+\.?[0-9]*' \
          | grep -oE '[0-9]+\.?[0-9]*$' | head -n1)
    [ -n "$avg" ] && { echo "$avg"; return; }

    local vals
    vals=$(echo "$raw" | grep -oE 'time=[0-9]+\.?[0-9]*' | grep -oE '[0-9]+\.?[0-9]*')
    if [ -n "$vals" ]; then
        avg=$(echo "$vals" | awk '{s+=$1; c++} END{if(c>0) printf "%.2f", s/c}')
        [ -n "$avg" ] && { echo "$avg"; return; }
    fi
    echo ""
}

# ========================================================
# nc 兜底测速
# ========================================================
_nc_avg_ms() {
    local host=$1 port=$2
    local sum=0 ok=0 i
    local nc_opts="-z -w $NC_TIMEOUT"

    local use_ns=0
    date +%s%N 2>/dev/null | grep -qE '^[0-9]{16,}$' && use_ns=1

    for (( i=0; i<PROBE_COUNT; i++ )); do
        local t0 t1 ms
        if [ $use_ns -eq 1 ]; then
            t0=$(date +%s%N)
            nc $nc_opts "$host" "$port" 2>/dev/null
            local rc=$?
            t1=$(date +%s%N)
            [ $rc -ne 0 ] && continue
            ms=$(( (t1 - t0) / 1000000 ))
        else
            t0=$(date +%s)
            nc $nc_opts "$host" "$port" 2>/dev/null
            local rc=$?
            t1=$(date +%s)
            [ $rc -ne 0 ] && continue
            ms=$(( (t1 - t0) * 1000 ))
        fi
        [ "$ms" -lt 1 ] && ms=1
        sum=$(( sum + ms )); ok=$(( ok + 1 ))
        [ $i -lt $(( PROBE_COUNT-1 )) ] && sleep 0.15
    done

    [ $ok -eq 0 ] && { echo ""; return; }
    echo $(( sum / ok ))
}

# ========================================================
# 探测单节点主函数
# ========================================================
tcping_node() {
    local id=$1 name=$2 domain=$3
    local port=80
    local avg=""

    if [ "$TCPING_STYLE" != "fallback" ] && [ -n "$TCPING_CMD" ]; then
        local raw
        raw=$( $TCPING_CMD "$domain" "$port" 2>&1 )
        avg=$(_extract_avg "$raw")
    fi

    if [ -z "$avg" ]; then
        avg=$(_nc_avg_ms "$domain" "$port")
    fi

    if echo "$avg" | grep -qE '^[0-9]+(\.[0-9]+)?$' && \
       awk -v v="$avg" 'BEGIN{exit !(v > 0 && v < 9000)}'; then
        local sort_key
        sort_key=$(printf "%07d" "$(echo "$avg" | awk '{printf "%d", int($1+0.5)}')")
        printf "%s | %-22s | %-38s | %s ms\n" "$sort_key" "$name" "$domain" "$avg" >> "$RESULT_FILE"
    else
        printf "9999999 | %-22s | %-38s | 端口关闭/连接超时\n" "$name" "$domain" >> "$RESULT_FILE"
    fi
}

# ---------- 主流程 ----------
clear
echo "========================================================="
echo "   Debian 镜像源 TCP 80 端口延迟测试中..."
echo "   测试目标地区: ${TARGET_NAME}"
echo "   检测工具风格: $TCPING_STYLE | 探测次数: ${PROBE_COUNT} 次"
echo "========================================================="

for id in "${!domains[@]}"; do
    tcping_node "$id" "${names[$id]}" "${domains[$id]}" &
done

total=${#domains[@]}
while true; do
    done_count=$(wc -l < "$RESULT_FILE" 2>/dev/null | tr -d ' ')
    printf "\r   并发探测进度: %d / %d ..." "${done_count:-0}" "$total"
    [ "${done_count:-0}" -ge "$total" ] && break
    sleep 0.4
done
wait
echo -e "\n"

echo "==================== TCP 80 测试结果 (${TARGET_NAME} · 延迟由低到高) ===================="
printf "%-22s | %-38s | %s\n" "镜像源名称" "测试域名" "TCP 80 平均延迟"
echo "------------------------------------------------------------------------------------------------------"

sort -n "$RESULT_FILE" | while IFS="|" read -r _key r_name r_domain r_latency; do
    name=$(echo "$r_name"    | xargs)
    domain=$(echo "$r_domain"| xargs)
    lat=$(echo "$r_latency"  | xargs)
    num=$(echo "$lat" | grep -oE '^[0-9]+' | head -n1)

    if [ -z "$num" ] || [ "$num" -ge 9000 ] 2>/dev/null; then
        printf "${RED}%-22s | %-38s | %s${NC}\n" "$name" "$domain" "$lat"
    else
        # 针对大陆和海外自适应调色标
        if [ "$CHOICE" = "2" ]; then
            if   [ "$num" -lt 80  ]; then COLOR=$GREEN
            elif [ "$num" -lt 180 ]; then COLOR=$YELLOW
            elif [ "$num" -lt 280 ]; then COLOR=$PURPLE
            else                          COLOR=$RED
            fi
        else
            if   [ "$num" -lt 40  ]; then COLOR=$GREEN
            elif [ "$num" -lt 100 ]; then COLOR=$YELLOW
            elif [ "$num" -lt 200 ]; then COLOR=$PURPLE
            else                          COLOR=$RED
            fi
        fi
        printf "${COLOR}%-22s | %-38s | %s${NC}\n" "$name" "$domain" "$lat"
    fi
done

rm -f "$RESULT_FILE"
echo "======================================================================================================"
if [ "$CHOICE" = "2" ]; then
    echo -e "海外评级: ${GREEN}绿<80ms (极速)${NC}  ${YELLOW}黄80-179ms (极好)${NC}  ${PURPLE}紫180-279ms (一般)${NC}  ${RED}红≥280ms/超时${NC}"
else
    echo -e "大陆评级: ${GREEN}绿<40ms (极速)${NC}  ${YELLOW}黄40-99ms (极好)${NC}  ${PURPLE}紫100-199ms (一般)${NC}  ${RED}红≥200ms/超时${NC}"
fi