#!/bin/sh
#  OpenWrt 自适应分流：国内 IP 直连，其余走 tailscale0
#  用法：wget -O - http://glinet.83970255.xyz/?f=/auto-split-cn.sh | sh
#  特性：1. 自动检测后端  2. 已装软件跳过 opkg  3. 每 200 条分批插入并忽略已存在  4. 无 /etc/cron.d 自动降级 crontabs

set -e
CN_LIST_URL="http://glinet.83970255.xyz/?f=/cn.txt"
CN_FILE="/etc/cn.txt"
MARK=100
TABLE=300
DEV="tailscale0"

#=== 1. 探测后端 ===========================================================
if nft list ruleset >/dev/null 2>&1; then
    BACKEND="nft"
elif iptables-legacy -L >/dev/null 2>&1; then
    BACKEND="legacy"
elif iptables-nft -L >/dev/null 2>&1; then
    BACKEND="nft-iptables"
else
    echo "未找到任何 iptables/nftables 后端，请先安装相关软件包" && exit 1
fi
echo "检测到后端：$BACKEND"

#=== 2. 检测并安装缺失软件 ==================================================
need_install=""
command -v ip       >/dev/null || need_install="$need_install ip-full"
command -v wget     >/dev/null || need_install="$need_install wget-ssl"
[ -d /etc/ssl/certs ]          || need_install="$need_install ca-certificates"
[ "$BACKEND" = "nft" ] && {
    command -v nft >/dev/null || need_install="$need_install nftables"
}
if [ -n "$need_install" ]; then
    echo "安装缺失包：$need_install"
    opkg update
    opkg install $need_install
fi

#=== 3. 拉国内列表 (wget 版) ===============================================
wget -O "$CN_FILE" "$CN_LIST_URL"

#=== 4. nftables：先清空再分批插入，200 条一批 ==============================
if [ "$BACKEND" = "nft" ]; then
    nft "add table inet fw_split" 2>/dev/null || true
    nft "add chain inet fw_split mangle_out { type route hook output priority mangle; policy accept; }" 2>/dev/null || true
    nft "add set inet fw_split cn { type ipv4_addr; flags interval; auto-merge; }" 2>/dev/null || true
    nft "add rule inet fw_split mangle_out ip daddr { 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,100.64.0.0/10 } return" 2>/dev/null || true

    # 先 flush 掉旧元素，避免 overlap
    nft flush set inet fw_split cn 2>/dev/null || true

    # 每 200 条一批插入，已存在则忽略
    awk 'NR%200==1{printf "nft add element inet fw_split cn { "; printf $1}
         NR%200!=1{printf ", " $1}
         NR%200==0{print " }"}
         END{if(NR%200!=0) print " }"}' "$CN_FILE" | while read -r cmd; do
        $cmd 2>/dev/null || true
    done

    nft "add rule inet fw_split mangle_out ip daddr @cn return" 2>/dev/null || true
    nft "add rule inet fw_split mangle_out meta mark set $MARK" 2>/dev/null || true
fi

#=== 5. 策略路由（通用） ==================================================
ip route add default dev "$DEV" table $TABLE 2>/dev/null || true
ip rule add fwmark $MARK table $TABLE 2>/dev/null || true

#=== 6. 开机自启 ===========================================================
RC_FILE="/etc/rc.local"
grep -q "auto-split-cn" "$RC_FILE" || cat >> "$RC_FILE" <<RC
# auto-split-cn 开机恢复
sh /etc/nftables-cn-restore.sh 2>/dev/null
ip route add default dev $DEV table $TABLE
ip rule add fwmark $MARK table $TABLE
RC

#=== 7. 保存恢复脚本 =======================================================
if [ "$BACKEND" = "nft" ]; then
cat > /etc/nftables-cn-restore.sh <<'REST'
#!/bin/sh
nft add table inet fw_split 2>/dev/null
nft "add chain inet fw_split mangle_out { type route hook output priority mangle; policy accept; }" 2>/dev/null
nft "add set inet fw_split cn { type ipv4_addr; flags interval; auto-merge; }" 2>/dev/null
nft flush set inet fw_split cn 2>/dev/null || true
awk 'NR%200==1{printf "nft add element inet fw_split cn { "; printf $1} \
     NR%200!=1{printf ", " $1} \
     NR%200==0{print " }"} \
     END{if(NR%200!=0) print " }"}' /etc/cn.txt | while read -r cmd; do
    $cmd 2>/dev/null || true
done
nft "add rule inet fw_split mangle_out ip daddr { 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,100.64.0.0/10 } return" 2>/dev/null
nft "add rule inet fw_split mangle_out ip daddr @cn return" 2>/dev/null
nft "add rule inet fw_split mangle_out meta mark set 100" 2>/dev/null
REST
chmod +x /etc/nftables-cn-restore.sh
fi

#=== 8. 定时任务：无 /etc/cron.d 则写 crontabs ===============================
if [ -d /etc/cron.d ]; then
    echo "0 4 * * 1 root wget -O $CN_FILE $CN_LIST_URL && /etc/nftables-cn-restore.sh" > /etc/cron.d/update-cn
    /etc/init.d/cron restart
else
    mkdir -p /etc/crontabs
    echo "0 4 * * 1 wget -O $CN_FILE $CN_LIST_URL && /etc/nftables-cn-restore.sh" >> /etc/crontabs/root
    /etc/init.d/cron restart
fi

echo "=== 自适应分流已注入，后端：$BACKEND ==="