#!/bin/sh
# udptunnel-setup – configure and start udptunnel on Debian/Ubuntu/Raspberry Pi OS
#
#   sudo udptunnel-setup udk       [options]   edge in UdK Berlin   (site 1)
#   sudo udptunnel-setup folkwang  [options]   edge in Folkwang Essen (site 2)
#   sudo udptunnel-setup broker    [options]   broker (amsel.udk.ai)
#   sudo udptunnel-setup status | logs | stop | start
#
# options:
#   --key KEY | --key-file FILE   shared secret (prompted for if omitted and none installed yet)
#   --mode p2p|relay|both         default p2p
#   --broker HOST:PORT            default amsel.udk.ai:40000
#   --bcast IP                    default 192.168.1.255
#   --dup N                       default 1
set -eu

ETC=/etc/udptunnel
SHARE=/usr/share/udptunnel

die() { echo "error: $*" >&2; exit 1; }
need_root() { [ "$(id -u)" = 0 ] || die "run as root (sudo udptunnel-setup ...)"; }

cmd=${1:-}
[ -n "$cmd" ] || { sed -n '2,16p' "$0" | sed 's/^# \{0,1\}//'; exit 2; }
shift

case "$cmd" in
status)
    for u in udptunnel-edge udptunnel-broker; do
        systemctl is-enabled -q $u 2>/dev/null || continue
        systemctl --no-pager status $u | head -5
        journalctl -u $u -n 15 --no-pager
    done
    exit 0 ;;
logs)
    exec journalctl -f -u udptunnel-edge -u udptunnel-broker ;;
stop|start|restart)
    need_root
    for u in udptunnel-edge udptunnel-broker; do
        systemctl is-enabled -q $u 2>/dev/null && systemctl $cmd $u
    done
    exit 0 ;;
udk|folkwang|broker) ;;
*) die "unknown command '$cmd' (udk | folkwang | broker | status | logs | stop | start)" ;;
esac

need_root
KEY="" KEYFILE="" MODE=p2p BROKER=amsel.udk.ai:40000 BCAST=192.168.1.255 DUP=1
while [ $# -gt 0 ]; do
    case "$1" in
    --key) KEY=$2; shift 2 ;;
    --key-file) KEYFILE=$2; shift 2 ;;
    --mode) MODE=$2; shift 2 ;;
    --broker) BROKER=$2; shift 2 ;;
    --bcast) BCAST=$2; shift 2 ;;
    --dup) DUP=$2; shift 2 ;;
    *) die "unknown option $1" ;;
    esac
done
case "$MODE" in p2p|relay|both) ;; *) die "--mode must be p2p, relay or both" ;; esac

# ---- key ----
install -d -m 750 -o root -g udptunnel "$ETC"
if [ -n "$KEYFILE" ]; then
    KEY=$(tr -d ' \r\n' < "$KEYFILE")
fi
if [ -z "$KEY" ] && [ ! -s "$ETC/key" ]; then
    printf 'Shared key (same on broker and both edges): '
    stty -echo 2>/dev/null || true
    read -r KEY
    stty echo 2>/dev/null || true
    echo
fi
if [ -n "$KEY" ]; then
    [ ${#KEY} -ge 16 ] || die "key too short"
    umask 027
    printf '%s\n' "$KEY" > "$ETC/key"
    chown root:udptunnel "$ETC/key"
    chmod 640 "$ETC/key"
fi

# ---- broker ----
if [ "$cmd" = broker ]; then
    systemctl daemon-reload
    systemctl enable udptunnel-broker >/dev/null 2>&1
    systemctl restart udptunnel-broker
    sleep 2
    journalctl -u udptunnel-broker -n 5 --no-pager
    if command -v ufw >/dev/null 2>&1 && ufw status 2>/dev/null | grep -q 'Status: active'; then
        ufw status | grep -q '40000/udp' || { echo "opening UDP 40000 in ufw"; ufw allow 40000/udp >/dev/null; }
    fi
    exit 0
fi

# ---- edge ----
sed -e "s|^BROKER=.*|BROKER=$BROKER|" -e "s|^MODE=.*|MODE=$MODE|" \
    -e "s|^BCAST=.*|BCAST=$BCAST|" -e "s|^DUP=.*|DUP=$DUP|" \
    "$SHARE/edge-$cmd.env" > "$ETC/edge.env"
chmod 644 "$ETC/edge.env"

if command -v ip >/dev/null 2>&1 && ! ip -4 addr | grep -q "brd $BCAST "; then
    echo "WARNING: no interface on this host has broadcast address $BCAST."
    echo "         Interfaces:"; ip -4 -br addr | sed 's/^/           /'
    echo "         Re-run with --bcast <your LAN broadcast address> if needed."
fi

systemctl daemon-reload
systemctl enable udptunnel-edge >/dev/null 2>&1
systemctl restart udptunnel-edge
echo "udptunnel edge '$cmd' started (mode $MODE, broker $BROKER). Waiting for connection..."
sleep 4
journalctl -u udptunnel-edge -n 12 --no-pager -o cat
echo
echo "Follow the log with:  sudo udptunnel-setup logs"
