#!/bin/bash
# -----------------------------------------
# 国内优化版 Reality 指纹抓取 + soga 自动更新
# -----------------------------------------

DEST_DOMAINS=(
    "www.cloudflare.com"
    "www.apple.com"
    "developer.apple.com"
    "www.microsoft.com"
    "www.bing.com"
)
FINGERPRINT_DIR="/etc/soga/fingerprints"
LOG_FILE="/var/log/auto_reality_fp.log"
SOGA_SERVICE="soga"
MAX_STORED_FPS=2      # 每个 IP 最多保存最近 5 个指纹
MAX_LOG_LINES=400     # 日志最多保留的行数

mkdir -p "$FINGERPRINT_DIR"
mkdir -p "$(dirname "$LOG_FILE")"

RESTART_NEEDED=false

log() {
    echo "[$(date '+%F %T')] $1" | tee -a "$LOG_FILE"
}

trim_log() {
    if [ -f "$LOG_FILE" ]; then
        tail -n $MAX_LOG_LINES "$LOG_FILE" > "${LOG_FILE}.tmp"
        mv "${LOG_FILE}.tmp" "$LOG_FILE"
    fi
}

get_fp() {
    local IP=$1
    local DOMAIN=$2
    openssl s_client -connect ${IP}:443 -servername ${DOMAIN} </dev/null 2>/dev/null \
        | openssl x509 -fingerprint -noout -sha256 \
        | awk -F= '{print $2}'
}

is_port_open() {
    local IP=$1
    timeout 2 bash -c "cat < /dev/null > /dev/tcp/${IP}/443" 2>/dev/null
}

for DOMAIN in "${DEST_DOMAINS[@]}"; do
    IPS=$(dig +short "$DOMAIN")
    if [ -z "$IPS" ]; then
        log "[WARN] 域名 $DOMAIN 无法解析 IP"
        continue
    fi

    log "检查域名：$DOMAIN 解析到 IP：$IPS"

    for IP in $IPS; do
        if ! is_port_open "$IP"; then
            log "[WARN] $DOMAIN ($IP) 443端口不可访问，跳过"
            continue
        fi

        FP_FILE="$FINGERPRINT_DIR/${DOMAIN}_${IP}.fp"
        CURRENT_FP=$(get_fp "$IP" "$DOMAIN")

        if [ -z "$CURRENT_FP" ]; then
            log "[WARN] $DOMAIN ($IP) 获取指纹失败，跳过"
            continue
        fi

        if [ ! -f "$FP_FILE" ]; then
            echo "$CURRENT_FP" > "$FP_FILE"
            log "[INFO] $DOMAIN ($IP) 首次记录指纹：$CURRENT_FP"
            RESTART_NEEDED=true
            continue
        fi

        if grep -q "$CURRENT_FP" "$FP_FILE"; then
            log "[INFO] $DOMAIN ($IP) 指纹已存在：$CURRENT_FP"
        else
            log "[INFO] $DOMAIN ($IP) 检测到新指纹：$CURRENT_FP"
            (echo "$CURRENT_FP"; cat "$FP_FILE") | awk "NR<=$MAX_STORED_FPS" > "$FP_FILE"
            RESTART_NEEDED=true
        fi
    done
done

if [ "$RESTART_NEEDED" = true ]; then
    systemctl restart $SOGA_SERVICE
    log "[INFO] soga 已重启以更新 Reality 指纹"
fi

trim_log
