#!/usr/bin/env bash
# EDGE bench / field bridge launcher.
#
# Single-hop (legacy pos4↔pos5):
#   POG_EDGE_ROLE=office|pos4  FIXTURE_POS=…  sudo -E bash run_bridge_edge_bench.sh
#
# Hub / spoke wlan star:
#   EDGE_TOPOLOGY=hub   POG_EDGE_ROLE=hub   EDGE_BANK=0 EDGE_BANK_WLAN=1 …
#   EDGE_TOPOLOGY=spoke POG_EDGE_ROLE=spoke EDGE_SPOKE_ID=2 …
#
# Software tip still via update.sh / SCP — this launcher only brings tunnels + bridge.

set -euo pipefail

EDGE_ROOT="$(cd "$(dirname "$0")" && pwd)"
TIMING_ROOT="$(cd "${EDGE_ROOT}/.." && pwd)"

# Allow run_bridge_jun11_good.sh to run under EDGE without re-dispatching.
export ETHERGOLD_ENTRY=1

# shellcheck disable=SC1091
source "${EDGE_ROOT}/pog_edge_env.sh"

if [[ -z "${POG_EDGE_ROLE:-}" ]]; then
  echo "FATAL: copy bench.env.example to bench.env and set POG_EDGE_ROLE=office|pos4|hub|spoke" >&2
  exit 1
fi

FIXTURE_POS="${FIXTURE_POS:-}"
if [[ -z "${FIXTURE_POS}" ]]; then
  case "${POG_EDGE_ROLE}" in
    office|hub) FIXTURE_POS=5 ;;
    pos4) FIXTURE_POS=4 ;;
    spoke) FIXTURE_POS="${EDGE_SPOKE_ID:-4}" ;;
  esac
fi

# Seat label only — protocol-agnostic. Allow 1..99 (hub-spoke scale).
if ! [[ "${FIXTURE_POS}" =~ ^[1-9][0-9]?$ ]]; then
  echo "WARN: FIXTURE_POS unset/invalid; using 1 for log/socket routing only (not a run gate)" >&2
  FIXTURE_POS=1
fi

case "${POG_EDGE_ROLE}:${FIXTURE_POS}" in
  office:5|pos4:4|hub:*|spoke:*) ;;
  *)
    echo "WARN: unexpected role/pos pairing (got ${POG_EDGE_ROLE} pos${FIXTURE_POS})" >&2
    ;;
esac

echo "=== POG-EDGE bridge (role=${POG_EDGE_ROLE} topo=${EDGE_TOPOLOGY:-single-hop} pos=${FIXTURE_POS} bank=${EDGE_BANK}) ==="
echo "  eth_lan=${POG_EDGE_LAN_IF} (WireGuard only — not in bridge)"

if [[ "${EUID}" -ne 0 ]]; then
  echo "FATAL: run with sudo -E so tunnel_up can configure wg/gretap" >&2
  exit 1
fi

bash "${EDGE_ROOT}/tunnel_up.sh"
# tunnel_up may select gretap1+ / eg-sNN — re-read active name(s).
if [[ -f "${EDGE_ROOT}/.active_gretap" ]]; then
  GRETAP_IF="$(tr -d '\r\n' < "${EDGE_ROOT}/.active_gretap")"
  export GRETAP_IF
fi

bash "${EDGE_ROOT}/prep_eth_game_for_fixture.sh"

# ETH_PORTS = AF_PACKET game plane only.
#   hub/spoke (wlan-star): gretap(s) only — never wlan* (Wi-Fi is uplink / bank-wlan).
#   single-hop: optional copper GAME_IF (eth*) + gretap; reject wlan*.
_edge_is_wlan_if() {
  [[ "${1}" == wlan* ]]
}

_edge_game_if_for_ports() {
  local g="${POG_EDGE_GAME_IF:-}"
  if [[ -z "${g}" ]] || _edge_is_wlan_if "${g}"; then
    echo ""
  else
    echo "${g}"
  fi
}

build_eth_ports() {
  local ports=()
  local topo="${EDGE_TOPOLOGY:-}"
  local role="${POG_EDGE_ROLE:-${EDGE_ROLE:-}}"
  local game
  game="$(_edge_game_if_for_ports)"

  if [[ "${topo}" == "hub" || "${role}" == "hub" ]]; then
    if [[ -f "${EDGE_ROOT}/.active_spoke_gretaps" ]]; then
      while IFS= read -r g; do
        g="$(echo "${g}" | tr -d '\r\n')"
        [[ -n "${g}" ]] && ports+=("${g}")
      done < "${EDGE_ROOT}/.active_spoke_gretaps"
    fi
  elif [[ "${topo}" == "spoke" || "${role}" == "spoke" ]]; then
    if [[ -n "${GRETAP_IF}" ]]; then
      ports+=("${GRETAP_IF}")
    fi
  else
    # Single-hop copper EDGE: eth game leg + gretap.
    if [[ -n "${game}" ]]; then
      ports+=("${game}")
    fi
    if [[ -n "${GRETAP_IF}" ]]; then
      local found=0
      for p in "${ports[@]+"${ports[@]}"}"; do
        [[ "${p}" == "${GRETAP_IF}" ]] && found=1
      done
      if [[ "${found}" -eq 0 ]]; then
        ports+=("${GRETAP_IF}")
      fi
    fi
  fi
  local IFS=,
  echo "${ports[*]}"
}

ETH_PORTS="$(build_eth_ports)"
if [[ -z "${ETH_PORTS}" ]]; then
  echo "FATAL: no ETH_PORTS (need gretap and/or copper game if — not wlan*)" >&2
  exit 1
fi
export ETH_PORTS
# Link watch: copper game if when present; else uplink (may be wlan1) — not in ETH_PORTS.
_lw_game="$(_edge_game_if_for_ports)"
export LINK_WATCH_INTERFACE="${_lw_game:-${POG_EDGE_LAN_IF:-${EDGE_UPLINK:-${GRETAP_IF}}}}"
export LINK_DIAG_DEVICE="${LINK_WATCH_INTERFACE}"
export FIXTURE_LINK_ARP=0
export POG_EDGE_BENCH=1
export EDGE_TID_UNICAST="${EDGE_TID_UNICAST:-1}"
export EDGE_BANK_WLAN="${EDGE_BANK_WLAN:-0}"
export EDGE_TOPOLOGY="${EDGE_TOPOLOGY:-}"
export EDGE_BANK="${EDGE_BANK:-0}"

echo "  eth_ports=${ETH_PORTS}"
echo "  link_watch=${LINK_WATCH_INTERFACE} (wlan* never in ETH_PORTS)"

REAL_USER="${SUDO_USER:-topbox}"

cd "${TIMING_ROOT}"
sudo -u "${REAL_USER}" env \
  ETHERGOLD_ENTRY=1 \
  FIXTURE_POS="${FIXTURE_POS}" \
  CHANNEL="${CHANNEL:-both}" \
  ETH_PORTS="${ETH_PORTS}" \
  FIXTURE_LINK_ARP="${FIXTURE_LINK_ARP}" \
  LINK_WATCH_INTERFACE="${LINK_WATCH_INTERFACE}" \
  LINK_DIAG_DEVICE="${LINK_DIAG_DEVICE}" \
  POG422_UARTD="${POG422_UARTD:-0}" \
  POG_EDGE_BENCH=1 \
  EDGE_MODE="${EDGE_MODE:-1}" \
  EDGE_TOPOLOGY="${EDGE_TOPOLOGY:-}" \
  EDGE_BANK="${EDGE_BANK}" \
  EDGE_SPOKE_ID="${EDGE_SPOKE_ID:-}" \
  EDGE_BANK_WLAN="${EDGE_BANK_WLAN}" \
  EDGE_TID_UNICAST="${EDGE_TID_UNICAST}" \
  EDGE_UPLINK="${EDGE_UPLINK:-}" \
  EDGE_UPLINK_IP="${EDGE_UPLINK_IP:-}" \
  EDGE_FLEET_HMAC_KEY_FILE="${EDGE_FLEET_HMAC_KEY_FILE:-}" \
  EDGE_HUB_WG_PUB="${EDGE_HUB_WG_PUB:-}" \
  VERBOSE="${VERBOSE:-1}" \
  CLEAR_CAPTURE="${CLEAR_CAPTURE:-1}" \
  FIXTURE_LAB_WITHHOLD_STATUS_0D="${FIXTURE_LAB_WITHHOLD_STATUS_0D:-${LAB_WITHHOLD_STATUS_0D:-0}}" \
  FIXTURE_LAB_WITHHOLD_STATUS_0D_COUNT="${FIXTURE_LAB_WITHHOLD_STATUS_0D_COUNT:-${LAB_WITHHOLD_STATUS_0D_COUNT:-1}}" \
  LAB_WITHHOLD_STATUS_0D="${LAB_WITHHOLD_STATUS_0D:-${FIXTURE_LAB_WITHHOLD_STATUS_0D:-0}}" \
  LAB_WITHHOLD_STATUS_0D_COUNT="${LAB_WITHHOLD_STATUS_0D_COUNT:-${FIXTURE_LAB_WITHHOLD_STATUS_0D_COUNT:-1}}" \
  bash "${TIMING_ROOT}/run_bridge_jun11_good.sh"
