#!/bin/bash
#
# Add the SIYI R1M factory-subnet address to the N100 Ethernet port.
#
# R1M ships at 192.168.144.25/24 and usually sits on a direct Ethernet
# cable or PoE injector with no DHCP server. Ubuntu leaves that NIC with
# link but no IPv4 address, so packets to 192.168.144.25 follow the default
# route out of the internet/LAN port and RTSP fails.
#
# The Raspberry Pi Strike image has a Pi-specific eth0 alias helper. N100
# boxes use unpredictable names such as enp1s0/enp3s0 and often have two
# Ethernet ports, so this helper auto-selects the R1M-side port.

set -euo pipefail

ALIAS_CIDR="${AIR_N100_R1M_ALIAS:-192.168.144.1/24}"
ALIAS_RE='inet 192\.168\.144\.[0-9]+/'
IFACE_FILE="${AIR_N100_R1M_IFACE_FILE:-/etc/air/r1m-iface}"

log() { echo "air-n100-r1m-alias: $*" >&2; }

if [ "$(uname -m)" != "x86_64" ]; then
    log "not x86_64; skipping"
    exit 0
fi

if ip -4 addr show | grep -Eq "$ALIAS_RE"; then
    log "a 192.168.144.0/24 address is already configured; nothing to do"
    exit 0
fi

is_wired_iface() {
    local iface="$1"
    case "$iface" in
        lo|zt*|tailscale*|tun*|tap*|wg*|docker*|br-*|veth*|virbr*|wl*|wlan*|p2p-*)
            return 1
            ;;
    esac
    [ -r "/sys/class/net/${iface}/type" ] || return 1
    [ "$(cat "/sys/class/net/${iface}/type" 2>/dev/null || echo 0)" = "1" ] || return 1
    return 0
}

has_carrier() {
    local iface="$1"
    [ "$(cat "/sys/class/net/${iface}/carrier" 2>/dev/null || echo 0)" = "1" ]
}

has_ipv4() {
    ip -4 addr show dev "$1" | grep -q 'inet '
}

has_default_route() {
    ip route show default dev "$1" | grep -q '^default '
}

pick_iface() {
    if [ -n "${AIR_N100_R1M_IFACE:-}" ]; then
        printf '%s\n' "$AIR_N100_R1M_IFACE"
        return 0
    fi
    if [ -r "$IFACE_FILE" ]; then
        local file_iface
        file_iface="$(sed -n '1{s/[[:space:]]//g;p;q}' "$IFACE_FILE" 2>/dev/null || true)"
        if [ -n "$file_iface" ]; then
            printf '%s\n' "$file_iface"
            return 0
        fi
    fi

    local ifaces=()
    local iface
    while IFS= read -r iface; do
        is_wired_iface "$iface" || continue
        has_carrier "$iface" || continue
        ifaces+=("$iface")
    done < <(find /sys/class/net -maxdepth 1 -mindepth 1 -printf '%f\n' | sort)

    # Best R1M signal on dual-NIC N100: link is up but DHCP did not assign
    # any IPv4 address. That is exactly a directly attached R1M / PoE injector.
    for iface in "${ifaces[@]}"; do
        if ! has_ipv4 "$iface"; then
            printf '%s\n' "$iface"
            return 0
        fi
    done

    # If every wired port has an address, prefer a non-default-route port.
    for iface in "${ifaces[@]}"; do
        if ! has_default_route "$iface"; then
            printf '%s\n' "$iface"
            return 0
        fi
    done

    # Single-NIC bench setup: adding an alias alongside DHCP is harmless.
    if [ "${#ifaces[@]}" -gt 0 ]; then
        printf '%s\n' "${ifaces[0]}"
        return 0
    fi
    return 1
}

IFACE="$(pick_iface || true)"
if [ -z "$IFACE" ]; then
    log "no wired carrier interface found; no alias configured"
    exit 0
fi
if ! ip link show "$IFACE" >/dev/null 2>&1; then
    log "${IFACE} not present; no alias configured"
    exit 0
fi
if ip -4 addr show dev "$IFACE" | grep -Eq "$ALIAS_RE"; then
    log "${IFACE} already has a 192.168.144.0/24 address; nothing to do"
    exit 0
fi

ip link set "$IFACE" up
ip addr add "$ALIAS_CIDR" dev "$IFACE"
log "added ${ALIAS_CIDR} to ${IFACE}"
