#!/usr/bin/env bash
# 自动化配置本端机器与中国内地机器之间的SNAT与策略路由
# 需在本端机器(root)执行，脚本将：
# 1. 读取两端网卡信息
# 2. 在本端机器上开启IPv4转发并创建仅包含SNAT的nft规则
# 3. 通过SSH登录中国内地机器，设置默认路由经由本端SD-WAN并为eth0维持原网关的策略路由
# 4. 为nft与中国内地侧路由分别创建systemd持久化服务

set -euo pipefail
export LC_ALL=C

LOG_PREFIX="[HaloCloud组网脚本]"

info() {
  echo -e "${LOG_PREFIX} $*"
}

warn() {
  echo -e "${LOG_PREFIX} [警告] $*" >&2
}

die() {
  echo -e "${LOG_PREFIX} [错误] $*" >&2
  exit 1
}

on_error() {
  local exit_code=$1
  local line_no=$2
  if [[ $exit_code -ne 0 ]]; then
    warn "脚本在第${line_no}行失败，退出码=${exit_code}"
  fi
}

trap 'on_error $? $LINENO' ERR

PKG_MGR=""
PKG_INSTALL_CMD=()
PKG_UPDATED=0

A_IP=""
A_PASS=""
A_HOSTNAME=""
A_NIC_INFO=""
A_ADDR_LIST=()
A_SD_WAN_IF=""
A_ETH0_IP=""
A_ETH0_GW=""
A_ETH0_HAS_IPV4=0
A_ETH0_IP6=""
A_ETH1_IP=""
A_ETH1_GW=""
A_ETH1_HAS_IPV4=0
A_ETH1_IP6=""

LOCAL_HOSTNAME=""
LOCAL_NIC_INFO=""
B_SD_WAN_IF=""
B_SD_WAN_IP=""
B_WAN_IF=""
B_WAN_IP=""
B_WAN_GW=""

NFT_SCRIPT_PATH="/usr/local/sbin/ab-nft-restore.sh"
NFT_SERVICE_PATH="/etc/systemd/system/ab-nft.service"
SYSCTL_FILE="/etc/sysctl.d/99-ab-nat.conf"

REMOTE_ROUTE_SCRIPT="/usr/local/sbin/ab-route-setup.sh"
REMOTE_ROUTE_SERVICE="/etc/systemd/system/ab-route-setup.service"

validate_ipv4() {
  local ip=$1
  if [[ ! $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
    die "IP地址 $ip 格式不正确"
  fi
  IFS='.' read -r -a octets <<<"$ip"
  for octet in "${octets[@]}"; do
    if ((octet < 0 || octet > 255)); then
      die "IP地址 $ip 含非法段"
    fi
  done
}

require_root() {
  if [[ $EUID -ne 0 ]]; then
    die "请使用root权限运行此脚本"
  fi
}

detect_pkg_manager() {
  if command -v apt-get >/dev/null 2>&1; then
    PKG_MGR="apt"
    PKG_INSTALL_CMD=(apt-get install -y)
  elif command -v dnf >/dev/null 2>&1; then
    PKG_MGR="dnf"
    PKG_INSTALL_CMD=(dnf install -y)
  elif command -v yum >/dev/null 2>&1; then
    PKG_MGR="yum"
    PKG_INSTALL_CMD=(yum install -y)
  else
    die "无法识别包管理器(仅支持apt/dnf/yum)"
  fi
}

update_pkg_index_if_needed() {
  if [[ $PKG_UPDATED -eq 1 ]]; then
    return
  fi
  case "$PKG_MGR" in
    apt)
      info "刷新apt软件源"
      apt-get update -y >/dev/null
      ;;
    dnf|yum)
      # dnf/yum安装时会自动处理元数据
      :
      ;;
  esac
  PKG_UPDATED=1
}

ensure_package() {
  local pkg=$1
  local binary=$2
  if command -v "$binary" >/dev/null 2>&1; then
    return
  fi
  update_pkg_index_if_needed
  info "安装依赖包: $pkg"
  "${PKG_INSTALL_CMD[@]}" "$pkg" >/dev/null
}

prompt_inputs() {
  read -r -p "请输入中国内地机器 SD-WAN 的IP地址: " A_IP
  validate_ipv4 "$A_IP"
  read -r -s -p "请输入中国内地机器 root 密码: " A_PASS
  echo ""
  if [[ -z $A_PASS ]]; then
    die "密码不能为空"
  fi
}

ssh_remote() {
  local raw_cmd=$1
  local quoted=""
  printf -v quoted '%q' "$raw_cmd"
  sshpass -p "$A_PASS" ssh \
    -o StrictHostKeyChecking=no \
    -o UserKnownHostsFile=/dev/null \
    -o PreferredAuthentications=password \
    -o PubkeyAuthentication=no \
    -o LogLevel=ERROR \
    -o ConnectTimeout=15 \
    "root@${A_IP}" "LANG=C bash -c $quoted"
}

test_remote() {
  info "校验与中国内地机器的SSH连接..."
  if ! ssh_remote "true" >/dev/null 2>&1; then
    die "无法通过SSH连接中国内地机器，请确认IP/密码"
  fi
}

gather_local_info() {
  LOCAL_HOSTNAME=$(hostname -f 2>/dev/null || hostname)
  LOCAL_NIC_INFO=$(ip -br addr show | while IFS= read -r line; do
    case "$line" in
      lo[[:space:]]*) continue ;;
      *) printf '%s\n' "$line" ;;
    esac
  done)

  local route_line
  if ! route_line=$(ip route get "$A_IP" 2>/dev/null); then
    die "无法计算到中国内地机器($A_IP)的路由，请确认网络互通"
  fi

  B_SD_WAN_IF=$(awk '/dev/ {for (i=1; i<=NF; i++) if ($i=="dev") {print $(i+1); exit}}' <<<"$route_line")
  B_SD_WAN_IP=$(awk '/src/ {for (i=1; i<=NF; i++) if ($i=="src") {print $(i+1); exit}}' <<<"$route_line")
  if [[ -z $B_SD_WAN_IF || -z $B_SD_WAN_IP ]]; then
    die "无法解析本端到中国内地的接口及源IP"
  fi

  local default_line
  default_line=$(ip route show default 0.0.0.0/0 | head -n1 || true)
  if [[ -z $default_line ]]; then
    die "未找到本端默认路由，无法配置SNAT"
  fi

  B_WAN_IF=$(awk '/dev/ {for (i=1; i<=NF; i++) if ($i=="dev") {print $(i+1); exit}}' <<<"$default_line")
  B_WAN_GW=$(awk '/via/ {for (i=1; i<=NF; i++) if ($i=="via") {print $(i+1); exit}}' <<<"$default_line")
  if [[ -z $B_WAN_IF ]]; then
    die "无法确定默认出口网卡"
  fi
  local wan_cidr
  wan_cidr=$(ip -o -4 addr show dev "$B_WAN_IF" | awk '{print $4}' | head -n1)
  if [[ -z $wan_cidr ]]; then
    die "无法读取出口网卡($B_WAN_IF)的IPv4地址"
  fi
  B_WAN_IP=${wan_cidr%/*}
}

gather_remote_info() {
  A_HOSTNAME=$(ssh_remote "hostname -f 2>/dev/null || hostname")
  A_NIC_INFO=$(ssh_remote "ip -br addr show | while IFS= read -r line; do
    case \"\$line\" in
      lo[\ \	]*) continue ;;
      *) printf '%s\n' \"\$line\" ;;
    esac
  done")

  local remote_iface
  remote_iface=$(ssh_remote "ip -o -4 addr show | awk -v ip='$A_IP' '\$4 ~ (\"^\" ip \"/\") {print \$2; exit}'")
  if [[ -z $remote_iface ]]; then
    die "中国内地机器上找不到包含$A_IP的网卡"
  fi
  A_SD_WAN_IF=$remote_iface

  local addr_line
  addr_line=$(ssh_remote "ip -o -4 addr show dev '$A_SD_WAN_IF' | awk '\$4 ~ (\"^${A_IP}/\") {print \$4; exit}'" || true)
  if [[ -z $addr_line ]]; then
    warn "未能读取中国内地接口$A_SD_WAN_IF的CIDR，默认仅使用$A_IP"
  fi

  mapfile -t A_ADDR_LIST < <(ssh_remote "ip -o -4 addr show dev '$A_SD_WAN_IF' | awk '{print \$4}'")

  if [[ ${#A_ADDR_LIST[@]} -eq 0 ]]; then
    die "中国内地机器未检测到任何IPv4地址"
  fi

  if ssh_remote "[[ -d /sys/class/net/eth0 ]]" >/dev/null 2>&1; then
    local eth0_cidr
    eth0_cidr=$(ssh_remote "ip -o -4 addr show dev eth0 | awk '{print \$4}' | head -n1" || true)
    if [[ -n $eth0_cidr ]]; then
      A_ETH0_IP=${eth0_cidr%/*}
      A_ETH0_HAS_IPV4=1
      A_ETH0_GW=$(ssh_remote "ip -4 route show default dev eth0 | awk 'NR==1 {print \$3}'" || true)
    else
      A_ETH0_IP=""
      A_ETH0_GW=""
      A_ETH0_IP6=$(ssh_remote "ip -o -6 addr show dev eth0 | awk '{print \$4}' | head -n1" || true)
    fi
  else
    A_ETH0_IP=""
    A_ETH0_GW=""
    A_ETH0_HAS_IPV4=0
    A_ETH0_IP6=""
  fi

  if ssh_remote "[[ -d /sys/class/net/eth1 ]]" >/dev/null 2>&1; then
    local eth1_cidr
    eth1_cidr=$(ssh_remote "ip -o -4 addr show dev eth1 | awk '{print \$4}' | head -n1" || true)
    if [[ -n $eth1_cidr ]]; then
      A_ETH1_IP=${eth1_cidr%/*}
      A_ETH1_HAS_IPV4=1
      A_ETH1_GW=$(ssh_remote "ip -4 route show default dev eth1 | awk 'NR==1 {print \$3}'" || true)
    else
      A_ETH1_IP=""
      A_ETH1_GW=""
      A_ETH1_IP6=$(ssh_remote "ip -o -6 addr show dev eth1 | awk '{print \$4}' | head -n1" || true)
    fi
  else
    A_ETH1_IP=""
    A_ETH1_GW=""
    A_ETH1_HAS_IPV4=0
    A_ETH1_IP6=""
  fi
}

enable_ip_forward() {
  mkdir -p "$(dirname "$SYSCTL_FILE")"
  if [[ -f $SYSCTL_FILE ]]; then
    if grep -q 'net\.ipv4\.ip_forward' "$SYSCTL_FILE"; then
      sed -i 's/^.*net\.ipv4\.ip_forward.*/net.ipv4.ip_forward = 1/' "$SYSCTL_FILE"
    else
      echo "net.ipv4.ip_forward = 1" >>"$SYSCTL_FILE"
    fi
  else
    cat >"$SYSCTL_FILE" <<EOF
# 自动生成，确保本端机器能转发IPv4
net.ipv4.ip_forward = 1
EOF
  fi
  sysctl -w net.ipv4.ip_forward=1 >/dev/null
}

build_nft_elements() {
  local -a unique_list=()
  declare -A seen=()
  for cidr in "${A_ADDR_LIST[@]}"; do
    local ip=${cidr%/*}
    [[ -z $ip ]] && continue
    if [[ -z ${seen[$ip]+x} ]]; then
      seen[$ip]=1
      unique_list+=("$ip")
    fi
  done
  if [[ ${#unique_list[@]} -eq 0 ]]; then
    unique_list+=("$A_IP")
  fi
  local joined=""
  for ip in "${unique_list[@]}"; do
    if [[ -z $joined ]]; then
      joined="$ip"
    else
      joined="$joined, $ip"
    fi
  done
  echo "$joined"
}

deploy_nft() {
  ensure_package "nftables" "nft"
  enable_ip_forward

  local elements
  elements=$(build_nft_elements)
  mkdir -p "$(dirname "$NFT_SCRIPT_PATH")"
cat >"$NFT_SCRIPT_PATH" <<EOF
#!/usr/bin/env bash
set -euo pipefail
set +o braceexpand
PATH=/sbin:/usr/sbin:/bin:/usr/bin

nft delete table ip ab_snat >/dev/null 2>&1 || true
nft -f - <<'NFT'
table ip ab_snat {
  set a_sources {
    type ipv4_addr
    elements = { $elements }
  }

  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
    iifname "$B_SD_WAN_IF"
    oifname "$B_WAN_IF"
    ip saddr @a_sources masquerade
  }
}
NFT
EOF
  chmod 700 "$NFT_SCRIPT_PATH"

  cat >"$NFT_SERVICE_PATH" <<EOF
[Unit]
Description=AB SNAT 规则加载
After=network-online.target network.target NetworkManager.service systemd-networkd.service networking.service
Wants=network-online.target
Requires=network-online.target
PartOf=systemd-networkd.service NetworkManager.service networking.service

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/ab-nft-restore.sh
RemainAfterExit=yes
Restart=on-failure
RestartSec=3

[Install]
WantedBy=multi-user.target network-online.target
EOF

  systemctl daemon-reload
  bash "$NFT_SCRIPT_PATH"
  systemctl enable --now ab-nft.service >/dev/null
}

deploy_remote_routes() {
  info "在中国内地机器创建策略路由脚本..."
  local table_name="ab_eth0"
  local table_id=100
  local eth1_table_name="ab_eth1"
  local eth1_table_id=110
  local sdwan_table_name="ab_sdwan"
  local sdwan_table_id=90
  local sdwan_rule_priority=2000
  local local_net_rule_priority=1900
  local eth0_rule_priority=1000
  local eth1_rule_priority=1001

  local remote_script
  remote_script=$(cat <<EOF
#!/usr/bin/env bash
set -euo pipefail
PATH=/sbin:/usr/sbin:/bin:/usr/bin

SDWAN_TABLE_ID=$sdwan_table_id
SDWAN_TABLE_NAME="$sdwan_table_name"
SDWAN_RULE_PRIORITY=$sdwan_rule_priority
LOCAL_NET_RULE_PRIORITY=$local_net_rule_priority

ETH0_TABLE_ID=$table_id
ETH0_TABLE_NAME="$table_name"
ETH0_RULE_PRIORITY=$eth0_rule_priority

ETH1_TABLE_ID=$eth1_table_id
ETH1_TABLE_NAME="$eth1_table_name"
ETH1_RULE_PRIORITY=$eth1_rule_priority

ETH_LINK_DEV="$A_SD_WAN_IF"
ETH_LINK_GW="$B_SD_WAN_IP"
ETH0_DEV="eth0"
ETH0_GW="$A_ETH0_GW"
ETH0_SRC="$A_ETH0_IP"
ETH0_HAS_IPV4="$A_ETH0_HAS_IPV4"
ETH1_DEV="eth1"
ETH1_GW="$A_ETH1_GW"
ETH1_SRC="$A_ETH1_IP"
ETH1_HAS_IPV4="$A_ETH1_HAS_IPV4"

ensure_table_entry() {
  local table_id=\$1
  local table_name=\$2
  local table_file="/etc/iproute2/rt_tables"
  mkdir -p "/etc/iproute2"
  touch "\$table_file"
  if ! grep -qE "^\\s*\${table_id}\\s+\${table_name}\\s*\$" "\$table_file"; then
    echo "\${table_id} \${table_name}" >>"\$table_file"
  fi
}

cleanup_src_rules() {
  local src=\$1
  local table=\$2
  ip rule show | awk -v table="\$table" -v src="\$src" '\$0 ~ ("from " src "/32") && \$0 ~ ("lookup " table) {gsub(/:$/,"",\$1); print \$1}' | while read -r prio; do
    [[ -z "\$prio" ]] && continue
    ip rule del priority "\$prio" || true
  done
}

cleanup_table_rules() {
  local table=\$1
  ip rule show | awk -v table="\$table" '\$0 ~ ("lookup " table) {gsub(/:$/,"",\$1); print \$1}' | while read -r prio; do
    [[ -z "\$prio" ]] && continue
    ip rule del priority "\$prio" || true
  done
}

dev_exists() {
  local dev=\$1
  [[ -n "\$dev" ]] && [[ -e "/sys/class/net/\$dev" ]]
}

add_local_net_rules() {
  # 确保本机已连接网段继续走main表，避免被默认sdwan规则覆盖
  ip -o -4 addr show scope global | awk '{print \$4}' | while read -r cidr; do
    [[ -z "\$cidr" ]] && continue
    ip rule add priority "\$LOCAL_NET_RULE_PRIORITY" to "\$cidr" lookup main 2>/dev/null || true
  done
}

setup_sdwan_policy() {
  if ! dev_exists "\$ETH_LINK_DEV"; then
    echo "SDWAN接口(\$ETH_LINK_DEV)不存在，跳过sdwan策略"
    return 0
  fi
  ensure_table_entry "\$SDWAN_TABLE_ID" "\$SDWAN_TABLE_NAME"
  ip route replace table "\$SDWAN_TABLE_NAME" default via "\$ETH_LINK_GW" dev "\$ETH_LINK_DEV" 2>/dev/null || true
  cleanup_table_rules "\$SDWAN_TABLE_NAME"
  add_local_net_rules
  ip rule del priority "\$SDWAN_RULE_PRIORITY" 2>/dev/null || true
  ip rule add priority "\$SDWAN_RULE_PRIORITY" lookup "\$SDWAN_TABLE_NAME"
}

setup_eth0_policy() {
  if ! dev_exists "\$ETH0_DEV"; then
    echo "eth0接口不存在，跳过eth0策略路由"
    return 0
  fi
  if [[ "\$ETH0_HAS_IPV4" != "1" ]]; then
    echo "eth0未检测到IPv4，跳过eth0策略路由"
    return 0
  fi
  if [[ -z "\$ETH0_GW" || -z "\$ETH0_SRC" ]]; then
    echo "eth0缺少IPv4网关或地址，跳过eth0策略路由"
    return 0
  fi
    ensure_table_entry "\$ETH0_TABLE_ID" "\$ETH0_TABLE_NAME"
    ip route replace table "\$ETH0_TABLE_NAME" default via "\$ETH0_GW" dev "\$ETH0_DEV"
    cleanup_src_rules "\$ETH0_SRC" "\$ETH0_TABLE_NAME"
    ip rule del priority "\$ETH0_RULE_PRIORITY" 2>/dev/null || true
    ip rule add from "\$ETH0_SRC/32" table "\$ETH0_TABLE_NAME" priority "\$ETH0_RULE_PRIORITY"
}

setup_eth1_policy() {
  if ! dev_exists "\$ETH1_DEV"; then
    echo "eth1接口不存在，跳过eth1策略路由"
    return 0
  fi
  if [[ "\$ETH1_HAS_IPV4" != "1" ]]; then
    echo "eth1未检测到IPv4，跳过eth1策略路由"
    return 0
  fi
  if [[ -z "\$ETH1_SRC" ]]; then
    echo "eth1缺少IPv4地址，跳过eth1策略路由"
    return 0
  fi
    ensure_table_entry "\$ETH1_TABLE_ID" "\$ETH1_TABLE_NAME"
    # 即便没有网关，也复制直连路由，保证源进源出
    ip route flush table "\$ETH1_TABLE_NAME" >/dev/null 2>&1 || true
    ip -4 route show dev "\$ETH1_DEV" scope link 2>/dev/null | while read -r r; do
      [[ -z "\$r" ]] && continue
      ip route replace table "\$ETH1_TABLE_NAME" \$r
    done || true
    if [[ -n "\$ETH1_GW" ]]; then
      ip route replace table "\$ETH1_TABLE_NAME" default via "\$ETH1_GW" dev "\$ETH1_DEV" 2>/dev/null || true
    fi
    cleanup_src_rules "\$ETH1_SRC" "\$ETH1_TABLE_NAME"
    ip rule del priority "\$ETH1_RULE_PRIORITY" 2>/dev/null || true
    ip rule add from "\$ETH1_SRC/32" table "\$ETH1_TABLE_NAME" priority "\$ETH1_RULE_PRIORITY"
}

setup_sdwan_policy
setup_eth0_policy
setup_eth1_policy
EOF
)

  ssh_remote "cat <<'__AB__' > $REMOTE_ROUTE_SCRIPT
$remote_script
__AB__"
  ssh_remote "chmod 700 $REMOTE_ROUTE_SCRIPT"

  local service_unit
  service_unit=$(cat <<EOF
[Unit]
Description=AB 默认路由&策略路由持久化
After=network-online.target network.target NetworkManager.service systemd-networkd.service networking.service
Wants=network-online.target
Requires=network-online.target
PartOf=systemd-networkd.service NetworkManager.service networking.service

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/ab-route-setup.sh
RemainAfterExit=yes
Restart=on-failure
RestartSec=3

[Install]
WantedBy=multi-user.target network-online.target
EOF
)

  ssh_remote "cat <<'__ABUNIT__' > $REMOTE_ROUTE_SERVICE
$service_unit
__ABUNIT__"

  ssh_remote "systemctl daemon-reload"
  ssh_remote "systemctl enable --now $(basename "$REMOTE_ROUTE_SERVICE")"
}

configure_remote_dns() {
  info "在中国内地机器配置DNS为Cloudflare(1.1.1.1/1.0.0.1)..."
  local dns_script
  dns_script=$(cat <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

DNS_FILE="/etc/resolv.conf"
STAMP="$(date +%Y%m%d%H%M%S)"
BACKUP_FILE="${DNS_FILE}.halocloud.${STAMP}.bak"

backup_existing() {
  if [[ -L "$DNS_FILE" ]]; then
    cp -L "$DNS_FILE" "$BACKUP_FILE" 2>/dev/null || cat "$DNS_FILE" >"$BACKUP_FILE"
  elif [[ -f "$DNS_FILE" ]]; then
    cp "$DNS_FILE" "$BACKUP_FILE" 2>/dev/null || cat "$DNS_FILE" >"$BACKUP_FILE"
  fi
}

write_dns() {
  if [[ -L "$DNS_FILE" ]]; then
    rm -f "$DNS_FILE"
  fi
  cat >"$DNS_FILE" <<DNSCONF
# Managed by HaloCloud组网脚本 at $STAMP
nameserver 1.1.1.1
nameserver 1.0.0.1
options timeout:2 attempts:2
DNSCONF
  chmod 644 "$DNS_FILE"
}

backup_existing
write_dns
EOF
)

  ssh_remote "cat <<'__DNS__' > /tmp/ab-set-dns.sh
$dns_script
__DNS__"
  ssh_remote "chmod 700 /tmp/ab-set-dns.sh && /tmp/ab-set-dns.sh && rm -f /tmp/ab-set-dns.sh"
}

configure_remote_ipv4_prefer() {
  info "在中国内地机器设置IPv4优先..."
  ssh_remote "GAI_CONF=/etc/gai.conf; touch \"\$GAI_CONF\"; \
if grep -q '^#precedence ::ffff:0:0/96  100' \"\$GAI_CONF\"; then \
  sed -i 's/^#precedence ::ffff:0:0\\/96  *100/precedence ::ffff:0:0\\/96  100/' \"\$GAI_CONF\"; \
elif ! grep -q '^precedence ::ffff:0:0/96  100' \"\$GAI_CONF\"; then \
  echo 'precedence ::ffff:0:0/96  100' >>\"\$GAI_CONF\"; \
fi; \
chmod 644 \"\$GAI_CONF\""
}

print_summary() {
  local eth0_ip_display
  local eth0_gw_display
  local eth0_note=""
  local eth0_listen_hint
  local eth0_ip6_display="${A_ETH0_IP6:-无IPv6}"
  local eth1_ip_display
  local eth1_gw_display
  local eth1_note=""
  local eth1_ip6_display="${A_ETH1_IP6:-无IPv6}"
  if [[ $A_ETH0_HAS_IPV4 -eq 1 ]]; then
    eth0_ip_display=${A_ETH0_IP:-无}
    eth0_gw_display=${A_ETH0_GW:-无}
    eth0_listen_hint="eth0的IPv4(${A_ETH0_IP:-未知})或IPv6(${eth0_ip6_display})"
  else
    eth0_ip_display="无(IPv6: ${eth0_ip6_display})"
    eth0_gw_display="无"
    eth0_note="(eth0仅IPv6，策略路由已跳过)"
    eth0_listen_hint="eth0的IPv6地址(${eth0_ip6_display})"
  fi
  if [[ $A_ETH1_HAS_IPV4 -eq 1 ]]; then
    eth1_ip_display=${A_ETH1_IP:-无}
    eth1_gw_display=${A_ETH1_GW:-无}
  else
    eth1_ip_display="无(IPv6: ${eth1_ip6_display})"
    eth1_gw_display="无"
    eth1_note="(eth1仅IPv6，策略路由已跳过)"
  fi

  info "=== 本端机器网卡信息 ==="
  printf '%s\n' "$LOCAL_NIC_INFO"
  info "=== 中国内地机器网卡信息 ==="
  printf '%s\n' "$A_NIC_INFO"

  cat <<EOF

-------------------------
本端机器 ($LOCAL_HOSTNAME):
  SD-WAN接口: $B_SD_WAN_IF ($B_SD_WAN_IP)
  WAN接口: $B_WAN_IF ($B_WAN_IP via $B_WAN_GW)
  SNAT脚本: $NFT_SCRIPT_PATH
  SNAT服务: $(basename "$NFT_SERVICE_PATH")
  sysctl文件: $SYSCTL_FILE

中国内地机器 ($A_HOSTNAME):
  中国内地接入接口: $A_SD_WAN_IF ($A_IP)
  eth0源IP: $eth0_ip_display | eth0网关: $eth0_gw_display $eth0_note
  eth1源IP: $eth1_ip_display | eth1网关: $eth1_gw_display $eth1_note
  路由脚本: $REMOTE_ROUTE_SCRIPT
  路由服务: $(basename "$REMOTE_ROUTE_SERVICE")
  IPv4优先: /etc/gai.conf (precedence ::ffff:0:0/96 100)
-------------------------

操作完成，如需查看状态:
  - 在本端机器执行: systemctl status ab-nft.service
  - 在中国内地机器执行: systemctl status ab-route-setup.service

附加提示:
  - 若希望UDP会话沿中国内地eth0原IP回源，请让业务程序仅监听中国内地eth0地址（当前探测为: $eth0_listen_hint），勿使用0.0.0.0/::通配监听，以确保响应始终匹配策略路由。
EOF
}

main() {
  require_root
  detect_pkg_manager
  ensure_package "sshpass" "sshpass"
  ensure_package "nftables" "nft"
  prompt_inputs
  test_remote
  gather_local_info
  gather_remote_info
  deploy_nft
  deploy_remote_routes
  configure_remote_dns
  configure_remote_ipv4_prefer
  print_summary
}

main "$@"

