#!/bin/sh
# pagan-wifi – wybór sieci Wi-Fi w PaganLinux (NetworkManager + nmcli).
#
# Uruchamiane z menu/pulpitu w sesji live, ale działa też w zainstalowanym
# systemie. Bez zależności poza nmcli (jest w NetworkManagerze) i xfce4-terminal
# jako hostem okna.
#
# Tryby:
#   pagan-wifi            – interaktywny wybór sieci
#   pagan-wifi --list     – sama lista wykrytych sieci (do diagnostyki/testów)
#   pagan-wifi --status   – stan interfejsów i adresy IP

set -u

# Terse output nmcli jest stabilny maszynowo, ale komunikaty dla użytkownika
# zostawiamy po polsku (piszemy je sami, nie tłumaczymy nmcli).
msg() { printf '%s\n' "$*"; }
err() { printf '%s\n' "$*" >&2; }

have_nmcli() {
    command -v nmcli >/dev/null 2>&1
}

# Nazwa interfejsu Wi-Fi (puste, jeśli brak karty).
wifi_iface() {
    nmcli -t -f DEVICE,TYPE device 2>/dev/null | awk -F: '$2 == "wifi" { print $1; exit }'
}

# Lista sieci: "SIGNAL<TAB>SECURITY<TAB>SSID", posortowana malejąco po sygnale.
#
# Uwaga na format: `nmcli -t` rozdziela pola dwukropkiem, a SSID może dwukropki
# zawierać. `-e no` wyłącza escapowanie (inaczej nmcli zapisuje je jako \:) i
# wtedy dwoma ostatnimi polami są zawsze SYGNAŁ i ZABEZPIECZENIA, a SSID to
# wszystko przed nimi.
list_networks() {
    nmcli -e no -t -f SSID,SIGNAL,SECURITY device wifi list --rescan yes 2>/dev/null | \
    awk -F: '
        NF >= 3 {
            sec = $NF
            sig = $(NF - 1)
            ssid = ""
            for (i = 1; i < NF - 1; i++) {
                ssid = ssid (i > 1 ? ":" : "") $i
            }
            if (ssid == "" || sig == "") {
                next
            }
            if (!(ssid in best) || sig + 0 > best[ssid] + 0) {
                best[ssid] = sig
                secs[ssid] = sec
            }
        }
        END {
            for (s in best) {
                printf "%s\t%s\t%s\n", best[s], secs[s], s
            }
        }
    ' | sort -rn
}

show_status() {
    msg "=== Interfejsy (nmcli device) ==="
    nmcli -t -f DEVICE,TYPE,STATE,CONNECTION device 2>/dev/null | tr ':' '\t' || true
    msg ""
    msg "=== Adresy IP ==="
    if command -v ip >/dev/null 2>&1; then
        ip -4 -brief addr 2>/dev/null || ip -4 addr 2>/dev/null || true
    fi
    msg ""
    msg "=== Łączność ==="
    if ping -c1 -W3 1.1.1.1 >/dev/null 2>&1; then
        msg "Internet: OK (1.1.1.1 odpowiada)"
    else
        msg "Internet: brak odpowiedzi z 1.1.1.1"
    fi
}

connect_network() {
    _ssid="$1"
    _sec="$2"

    _pass=""
    if [ "$_sec" != "--" ] && [ "$_sec" != "" ]; then
        printf 'Hasło do "%s" (nie będzie widoczne): ' "$_ssid"
        if command -v stty >/dev/null 2>&1; then
            stty -echo 2>/dev/null || true
            read -r _pass
            stty echo 2>/dev/null || true
            printf '\n'
        else
            read -r _pass
        fi
    fi

    msg "Łączenie z \"$_ssid\"..."
    if [ -n "$_pass" ]; then
        if nmcli device wifi connect "$_ssid" password "$_pass"; then
            _rc=0
        else
            _rc=1
        fi
    else
        if nmcli device wifi connect "$_ssid"; then
            _rc=0
        else
            _rc=1
        fi
    fi
    _pass=""

    if [ "$_rc" -eq 0 ]; then
        msg "Połączono."
    else
        err "Nie udało się połączyć. Sprawdź hasło albo spróbuj ponownie."
    fi
    msg ""
    show_status
    return "$_rc"
}

interactive() {
    if ! have_nmcli; then
        err "Brak polecenia nmcli. Zainstaluj/uruchom NetworkManager: sudo systemctl start NetworkManager"
        return 1
    fi

    _iface="$(wifi_iface)"
    if [ -z "$_iface" ]; then
        err "Nie wykryto karty Wi-Fi."
        err "Sprawdź, czy adapter jest widoczny: lsusb / ip link"
        err "Oraz czy sterownik się załadował: dmesg | grep -i firmware"
        msg ""
        show_status
        return 1
    fi

    msg "Karta Wi-Fi: $_iface"
    msg "Szukam sieci (chwilę to potrwa)..."
    _list="$(list_networks)"

    if [ -z "$_list" ]; then
        err "Nie znaleziono żadnej sieci Wi-Fi."
        return 1
    fi

    # Numerowana lista (zachowujemy SSID i zabezpieczenia w plikach tymczasowych).
    _tmp="$(mktemp)" || return 1
    printf '%s\n' "$_list" | awk -F'\t' '{ printf "%2d) %-32s %3s%%  %s\n", NR, $3, $1, $2 }'
    printf '%s\n' "$_list" > "$_tmp"

    printf '\nNumer sieci (lub "q" aby wyjść): '
    read -r _choice
    case "$_choice" in
        q|Q|"")
            rm -f "$_tmp"
            return 0
            ;;
    esac

    case "$_choice" in
        *[!0-9]*)
            err "Niepoprawny wybór."
            rm -f "$_tmp"
            return 1
            ;;
    esac

    _entry="$(sed -n "${_choice}p" "$_tmp")"
    rm -f "$_tmp"
    if [ -z "$_entry" ]; then
        err "Nie ma sieci o numerze $_choice."
        return 1
    fi

    _sig="$(printf '%s' "$_entry" | cut -f1)"
    _sec="$(printf '%s' "$_entry" | cut -f2)"
    _ssid="$(printf '%s' "$_entry" | cut -f3-)"

    connect_network "$_ssid" "$_sec"
    return $?
}

case "${1:-}" in
    --list)
        list_networks
        ;;
    --status)
        show_status
        ;;
    --help|-h)
        msg "pagan-wifi – wybór sieci Wi-Fi (NetworkManager)"
        msg "  pagan-wifi            interaktywny wybór sieci"
        msg "  pagan-wifi --list      lista wykrytych sieci"
        msg "  pagan-wifi --status    stan interfejsów i adresy IP"
        ;;
    *)
        interactive
        ;;
esac
