#!/usr/bin/env bash
# Persistently unmanage eth0/eth1 in NetworkManager (root-owned conf.d).
# Chain / copper hops: both ports unmanaged — no DHCP spam, no NM link churn.
# Edge (EDGE_MODE=1): 20- override re-manages EDGE_UPLINK only; game port stays unmanaged.
#
#   sudo bash install_nm_eth_unmanaged.sh
#   sudo bash install_nm_eth_unmanaged.sh --edge-uplink eth0 --edge-game eth1
#   sudo bash install_nm_eth_unmanaged.sh --clear-edge
#
# Idempotent. Safe to re-run from commission_prod_boot / update.sh / enable_edge.

if grep -q $'\r' "${BASH_SOURCE[0]}" 2>/dev/null; then
  sed -i 's/\r$//' "${BASH_SOURCE[0]}"
  exec bash "${BASH_SOURCE[0]}" "$@"
fi

set -euo pipefail

if [[ "${EUID}" -ne 0 ]]; then
  echo "FATAL: run with sudo" >&2
  exit 1
fi

NM_CONF_DIR="/etc/NetworkManager/conf.d"
BASE_CONF="${NM_CONF_DIR}/10-ethergold-unmanaged.conf"
EDGE_CONF="${NM_CONF_DIR}/20-ethergold-edge.conf"
EDGE_ENV="/etc/ethergold/edge.env"
if [[ ! -f "${EDGE_ENV}" && -f /etc/fixture/edge.env ]]; then
  EDGE_ENV="/etc/fixture/edge.env"
fi

EDGE_UPLINK_ARG=""
EDGE_GAME_ARG=""
CLEAR_EDGE=0
FLUSH_UNMANAGED=1

while [[ $# -gt 0 ]]; do
  case "$1" in
    --edge-uplink) EDGE_UPLINK_ARG="$2"; shift 2 ;;
    --edge-game) EDGE_GAME_ARG="$2"; shift 2 ;;
    --clear-edge) CLEAR_EDGE=1; shift ;;
    --no-flush) FLUSH_UNMANAGED=0; shift ;;
    -h|--help)
      sed -n '1,14p' "${BASH_SOURCE[0]}"
      exit 0
      ;;
    *)
      echo "Unknown option: $1" >&2
      exit 1
      ;;
  esac
done

mkdir -p "${NM_CONF_DIR}"

cat > "${BASE_CONF}" <<'EOF'
# EtherGold — copper/game ports must stay IP-less for AF_PACKET bridging.
# wlan0 stays managed (SSH / admin). Edge re-enables one uplink via 20-ethergold-edge.conf.
[keyfile]
unmanaged-devices=interface-name:eth0;interface-name:eth1
EOF
chmod 644 "${BASE_CONF}"

if [[ "${CLEAR_EDGE}" == "1" ]]; then
  rm -f "${EDGE_CONF}"
elif [[ -n "${EDGE_UPLINK_ARG}" ]]; then
  UPLINK="${EDGE_UPLINK_ARG}"
  GAME="${EDGE_GAME_ARG}"
  if [[ "${UPLINK}" == "eth0" ]]; then
    # LAN uplink on eth0 — leave eth1 (game) unmanaged.
    cat > "${EDGE_CONF}" <<'EOF'
# EtherGold POG-EDGE — eth0 is WG transport (managed); eth1 stays game/AF_PACKET.
[keyfile]
unmanaged-devices=interface-name:eth1
EOF
    chmod 644 "${EDGE_CONF}"
  elif [[ "${UPLINK}" == wlan* ]]; then
    # WiFi uplink — both eth ports stay unmanaged (base 10- is enough).
    rm -f "${EDGE_CONF}"
  else
    echo "FATAL: --edge-uplink must be eth0 or wlanN (got ${UPLINK})" >&2
    exit 1
  fi
  # GAME unused today (always eth1 or none); reserved for future dual-uplink layouts.
  : "${GAME:=}"
elif [[ -f "${EDGE_ENV}" ]] && grep -qE '^EDGE_MODE=1([[:space:]]|$)' "${EDGE_ENV}" 2>/dev/null; then
  # Preserve / sync edge override from live edge.env when no CLI edge flags.
  UPLINK=$(grep -E '^EDGE_UPLINK=' "${EDGE_ENV}" | head -1 | cut -d= -f2- | tr -d '\r' || true)
  UPLINK="${UPLINK:-eth0}"
  GAME=$(grep -E '^EDGE_GAME_IF=' "${EDGE_ENV}" | head -1 | cut -d= -f2- | tr -d '\r' || true)
  if [[ "${UPLINK}" == "eth0" ]]; then
    cat > "${EDGE_CONF}" <<'EOF'
# EtherGold POG-EDGE — eth0 is WG transport (managed); eth1 stays game/AF_PACKET.
[keyfile]
unmanaged-devices=interface-name:eth1
EOF
    chmod 644 "${EDGE_CONF}"
  else
    rm -f "${EDGE_CONF}"
  fi
  : "${GAME:=}"
fi

reload_nm() {
  if systemctl is-active NetworkManager >/dev/null 2>&1; then
    systemctl reload NetworkManager 2>/dev/null || systemctl restart NetworkManager
  elif command -v nmcli >/dev/null 2>&1; then
    nmcli general reload 2>/dev/null || true
  fi
}

reload_nm
# Give NM a moment to apply keyfile unmanaged list.
sleep 1

unmanaged_list=()
if [[ -f "${EDGE_CONF}" ]] && grep -q 'interface-name:eth1' "${EDGE_CONF}" \
  && ! grep -q 'interface-name:eth0' "${EDGE_CONF}"; then
  unmanaged_list=(eth1)
else
  unmanaged_list=(eth0 eth1)
fi

if [[ "${FLUSH_UNMANAGED}" == "1" ]]; then
  for p in "${unmanaged_list[@]}"; do
    if [[ -d "/sys/class/net/${p}" ]]; then
      ip addr flush dev "${p}" 2>/dev/null || true
      ip link set "${p}" nomaster 2>/dev/null || true
      ip link set "${p}" up 2>/dev/null || true
    fi
  done
fi

echo "=== nm_eth_unmanaged ==="
echo "base=${BASE_CONF}"
[[ -f "${EDGE_CONF}" ]] && echo "edge=${EDGE_CONF}" || echo "edge=(none)"
if command -v nmcli >/dev/null 2>&1; then
  for p in eth0 eth1 wlan0; do
    if [[ -d "/sys/class/net/${p}" ]]; then
      m=$(nmcli -g GENERAL.NM-MANAGED device show "${p}" 2>/dev/null || echo "?")
      echo "NM-MANAGED ${p}=${m}"
    fi
  done
fi
