#!/bin/sh
# wg-bounce — restart the wg1 tunnel without an interactive sudo password.
#
# macOS WireGuard (wg-quick) needs root to create the utun interface and
# install routes. This script invokes it via `sudo -n`. If the sudoers entry
# is missing, the script offers to install it from the bundled template
# (a single password prompt that won't be needed again).
#
# Usage:
#   wg-bounce                            # down + up the default config
#   wg-bounce <conf-path>                # down + up a specific .conf file
#
# Exit codes:
#   0 success
#   1 setup needed and the install prompt failed
#   2 wg-quick down or up failed

set -eu

conf=${1:-"$HOME/.wireguard/wg1.conf"}

if [ ! -r "$conf" ]; then
    echo "wg-bounce: missing config $conf" >&2
    exit 1
fi

# Resolve symlinks so $script_dir points at the real bin/ inside session-tools,
# letting us find ../share/. macOS /bin/sh lacks `readlink -f`, so walk it
# manually until we hit a non-symlink.
resolve_link() {
    target=$1
    while [ -L "$target" ]; do
        link=$(readlink "$target")
        case $link in
            /*) target=$link ;;
            *)  target=$(dirname "$target")/$link ;;
        esac
    done
    printf %s "$target"
}
script_path=$(resolve_link "$0")
script_dir=$(cd "$(dirname "$script_path")" && pwd)
sudoers_src="$script_dir/../share/wg-quick.sudoers"
sudoers_dst=/etc/sudoers.d/wg-quick

if ! sudo -n /opt/homebrew/bin/wg-quick --help >/dev/null 2>&1; then
    # Sudoers entry missing or doesn't apply yet. Try to install it from the
    # bundled template — this is the ONE prompt for a password we accept; all
    # subsequent wg-bounce runs are passwordless.
    if [ ! -r "$sudoers_src" ]; then
        echo "wg-bounce: sudoers template missing at $sudoers_src" >&2
        exit 1
    fi
    echo "wg-bounce: first run — installing $sudoers_dst (one-time sudo prompt)"
    # Validate the template before installing so a typo never lands in
    # /etc/sudoers.d (visudo -c -f checks parseability).
    if ! sudo visudo -c -f "$sudoers_src" >/dev/null; then
        echo "wg-bounce: $sudoers_src failed visudo syntax check" >&2
        exit 1
    fi
    if ! sudo install -m 0440 -o root -g wheel "$sudoers_src" "$sudoers_dst"; then
        echo "wg-bounce: failed to install $sudoers_dst" >&2
        exit 1
    fi
    # Re-check; should now succeed without prompting.
    if ! sudo -n /opt/homebrew/bin/wg-quick --help >/dev/null 2>&1; then
        echo "wg-bounce: sudoers installed but sudo still prompts — check $sudoers_dst" >&2
        exit 1
    fi
    echo "wg-bounce: setup complete; future runs won't prompt"
fi

echo "wg-bounce: down $conf"
# down may fail if the tunnel is already down — that's fine, we proceed to up.
sudo -n /opt/homebrew/bin/wg-quick down "$conf" 2>/dev/null || true

echo "wg-bounce: up $conf"
if ! sudo -n /opt/homebrew/bin/wg-quick up "$conf"; then
    echo "wg-bounce: wg-quick up failed" >&2
    exit 2
fi

# Brief reach test against the hub so the caller knows immediately whether
# the new endpoint is actually carrying packets.
echo "wg-bounce: waiting for handshake..."
for i in 1 2 3 4 5 6 7 8 9 10; do
    if ping -c 1 -W 1500 10.9.0.1 >/dev/null 2>&1; then
        echo "wg-bounce: hub reachable after ${i}s"
        exit 0
    fi
    sleep 1
done

echo "wg-bounce: hub (10.9.0.1) still unreachable after 10s — tunnel is up but no packets are flowing (check hotel wifi / NAT)." >&2
exit 2
