#!/bin/bash

# --- 邮件配置 ---
MailTo="hitmickeyq@qq.com"
Subject="[警告] 内网穿透服务异常重启通知"
SERVER_NAME=$(hostname)

# --- 监控配置 ---
CHECK_URLS=(
    "https://beszel-speedtest.mingqian.online"
    "https://ddns-speedtest.mingqian.online"
    "https://jellyfin-speedtest.mingqian.online"
    "https://filebrowser-speedtest.mingqian.online"
    "https://qbittorrent-speedtest.mingqian.online"
    "https://resiliosync-speedtest.mingqian.online"
    "https://preview-speedtest.mingqian.online"
    "https://pdf2zh-speedtest.mingqian.online"
    "https://sub-speedtest.mingqian.online"
)

# 动态计算阈值：失败数量达到总数的一半（向上取整），才算作“大面积瘫痪”
TOTAL_URLS=${#CHECK_URLS[@]}
THRESHOLD=$(( (TOTAL_URLS + 1) / 2 ))

KEYWORD="Faithfully yours, frp"
# KEYWORD="502 Bad Gateway" # rathole 可能会报这个
MAX_RETRIES=2     # 连续 2 轮大面积失败才执行重启（抗抖动）
INTERVAL=60 

BASE_DIR=$(cd "$(dirname "$0")"; pwd)
TEMP_DIR="$BASE_DIR/.monitor_frp_tmp"
# TEMP_DIR="$BASE_DIR/.monitor_rathole_tmp"

RETRY_FILE="$BASE_DIR/.monitor_retry_count"
[ ! -f "$RETRY_FILE" ] && echo 0 > "$RETRY_FILE"

echo "$(date '+%Y-%m-%d %H:%M:%S') - 内网穿透服务高级监控已启动。检测总数: $TOTAL_URLS, 报警阈值: $THRESHOLD"

while true; do
    [ -d "$TEMP_DIR" ] && rm -rf "$TEMP_DIR"
    mkdir -p "$TEMP_DIR"

    echo "------------------------------------------------"
    echo "$(date '+%Y-%m-%d %H:%M:%S') - 开始一轮并发探测..."

    for i in "${!CHECK_URLS[@]}"; do
        URL=${CHECK_URLS[$i]}
        (
            # 改进1：使用 if ! 捕获所有 curl 底层错误（DNS, TLS, 超时等）
            if ! HTTP_CODE=$(curl -skL -o "$TEMP_DIR/resp_$i" -w "%{http_code}" --max-time 10 "$URL" 2>/dev/null); then
                touch "$TEMP_DIR/fail_$i"
                echo "[!] 底层网络异常: $URL"
            else
                # 改进2：使用 Bash 内置读取，提升效率
                CONTENT=$(<"$TEMP_DIR/resp_$i")
                
                # 改进3：保留 502/504 和 KEYWORD 判断，不限制必须是 200 (FRP错误页通常是404)
                if [[ "$HTTP_CODE" == "502" ]] || [[ "$HTTP_CODE" == "504" ]] || [[ "$CONTENT" == *"$KEYWORD"* ]]; then
                    touch "$TEMP_DIR/fail_$i"
                    echo "[!] 穿透服务异常 (Code: $HTTP_CODE): $URL"
                else
                    echo "[✓] 正常 (Code: $HTTP_CODE): $URL"
                fi
            fi
        ) &
    done

    wait

    # 改进4：使用 find 替代 ls，避免通配符异常
    FAIL_COUNT=$(find "$TEMP_DIR" -maxdepth 1 -name "fail_*" | wc -l)
    
    # 清理网页内容缓存
    rm -f "$TEMP_DIR"/resp_*

    echo "探测结束。本轮失败数: $FAIL_COUNT / 阈值: $THRESHOLD"

    if [ "$FAIL_COUNT" -ge "$THRESHOLD" ]; then
        CURRENT_RETRY=$(cat "$RETRY_FILE")
        CURRENT_RETRY=$((CURRENT_RETRY + 1))
        echo "$CURRENT_RETRY" > "$RETRY_FILE"
        
        echo "$(date '+%Y-%m-%d %H:%M:%S') - [警告] 异常数达标。当前连续失败轮数: $CURRENT_RETRY"

        if [ "$CURRENT_RETRY" -ge "$MAX_RETRIES" ]; then
            echo "$(date '+%Y-%m-%d %H:%M:%S') - [触发动作] 达到连续失败上限，尝试重启服务..."
            
            # 改进5：增强 sudo 执行的错误捕获
            if sudo systemctl restart frpc.service; then
            # if sudo systemctl restart ratholec.service; then
                
                msg="服务器 [$SERVER_NAME] frp 隧道异常。\n\n状态：连续 $CURRENT_RETRY 轮探测异常数达标。\n异常链接数: $FAIL_COUNT / 总数: $TOTAL_URLS\n检查时间: $(date '+%Y-%m-%d %H:%M:%S')"
                # msg="服务器 [$SERVER_NAME] rathole 隧道异常。\n\n状态：连续 $CURRENT_RETRY 轮探测异常数达标。\n异常链接数: $FAIL_COUNT / 总数: $TOTAL_URLS\n检查时间: $(date '+%Y-%m-%d %H:%M:%S')"
                
                {
                    echo "To: $MailTo"
                    echo "Subject: $Subject"
                    echo "Date: $(date -R)"
                    echo "Content-Type: text/plain; charset=UTF-8"
                    echo
                    echo -e "$msg"
                } | msmtp -a default "$MailTo"
                echo "重启成功，已发送通知邮件。"
            else
                echo "[严重错误] sudo systemctl 重启命令执行失败！请检查用户权限或服务状态。"
            fi
            
            # 无论成功失败，触发后都重置计数器
            echo 0 > "$RETRY_FILE"
        fi
    else
        echo 0 > "$RETRY_FILE"
    fi

    rm -rf "$TEMP_DIR"
    sleep $INTERVAL
done
