#!/bin/sh
# Quick network configurator for the local console.
# Type 'a' at any prompt to abort, 'b' to go back.
set -e

abort() { echo "Aborted."; exit 0; }

ask() {
    # ask VARNAME "prompt" [default]
    # Sets VARNAME. Returns 1 on 'b' (back), calls abort on 'a'.
    _var="$1"; _prompt="$2"; _default="$3"
    while true; do
        if [ -n "$_default" ]; then
            printf "%s [%s] (b=back a=abort): " "$_prompt" "$_default"
        else
            printf "%s (b=back a=abort): " "$_prompt"
        fi
        read _input
        case "$_input" in
            a|A) abort ;;
            b|B) return 1 ;;
            "")
                if [ -n "$_default" ]; then
                    eval "$_var=\"\$_default\""
                    return 0
                else
                    echo "  Required — please enter a value."
                fi
                ;;
            *)
                eval "$_var=\"\$_input\""
                return 0
                ;;
        esac
    done
}

# ── Step 1: choose interface ───────────────────────────────────────────────────

choose_iface() {
    IFACES=$(ip -o link show | awk -F': ' '$2 != "lo" {print $2}' | cut -d@ -f1)
    if [ -z "$IFACES" ]; then
        echo "No network interfaces found."
        exit 1
    fi

    echo ""
    echo "Interfaces:"
    i=1
    for iface in $IFACES; do
        ip=$(ip -4 addr show "$iface" 2>/dev/null | awk '/inet /{print $2}' | head -1)
        echo "  $i) $iface  ${ip:-no IP}"
        i=$((i+1))
    done
    echo ""

    FIRST=$(echo "$IFACES" | head -1)
    while true; do
        printf "Interface number or name [%s] (a=abort): " "$FIRST"
        read INPUT
        case "$INPUT" in
            a|A) abort ;;
            "")
                IFACE="$FIRST"
                break
                ;;
            *)
                if echo "$INPUT" | grep -qE '^[0-9]+$'; then
                    IFACE=$(echo "$IFACES" | awk "NR==$INPUT")
                    if [ -z "$IFACE" ]; then
                        echo "  No interface #$INPUT — try again."
                        continue
                    fi
                else
                    # Validate name exists
                    if ! echo "$IFACES" | grep -qx "$INPUT"; then
                        echo "  Unknown interface '$INPUT' — try again."
                        continue
                    fi
                    IFACE="$INPUT"
                fi
                break
                ;;
        esac
    done
    echo "Selected: $IFACE"
}

# ── Step 2: choose mode ────────────────────────────────────────────────────────

choose_mode() {
    echo ""
    echo "  1) DHCP"
    echo "  2) Static IP"
    echo ""
    while true; do
        printf "Mode [1] (b=back a=abort): "
        read INPUT
        case "$INPUT" in
            a|A) abort ;;
            b|B) return 1 ;;
            ""|1) MODE=dhcp; break ;;
            2)    MODE=static; break ;;
            *) echo "  Enter 1 or 2." ;;
        esac
    done
}

# ── Step 3a: DHCP ─────────────────────────────────────────────────────────────

run_dhcp() {
    echo "Running DHCP on $IFACE..."
    dhclient -v "$IFACE"
}

# ── Step 3b: Static ───────────────────────────────────────────────────────────

run_static() {
    while true; do
        ask ADDR "IP address (e.g. 192.168.1.100/24)" || return 1
        # Basic format check: must contain a dot and a /
        if ! echo "$ADDR" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+$'; then
            echo "  Invalid format — use x.x.x.x/prefix (e.g. 192.168.1.10/24)."
            continue
        fi
        break
    done

    while true; do
        ask GW "Gateway (e.g. 192.168.1.1)" || return 1
        if ! echo "$GW" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'; then
            echo "  Invalid IP address."
            continue
        fi
        break
    done

    ask DNS "DNS server" "8.8.8.8" || return 1

    ip addr flush dev "$IFACE"
    ip addr add "$ADDR" dev "$IFACE"
    ip link set "$IFACE" up
    ip route add default via "$GW" 2>/dev/null || true
    echo "nameserver $DNS" > /etc/resolv.conf
    echo "Done."
}

# ── Main loop ─────────────────────────────────────────────────────────────────

choose_iface

while true; do
    choose_mode || { choose_iface; continue; }

    if [ "$MODE" = "dhcp" ]; then
        run_dhcp && break
    else
        run_static && break || continue
    fi
done

echo ""
ip -4 addr show "$IFACE"
