#!/bin/bash -e

NMCLI=(nmcli -f 'SSID,RATE,BARS,SECURITY' dev wifi)

function ask_pass() {
    local net="$1" p

    while [ "${#p}" -lt 8 ]; do
        p="$(zenity --entry --entry-text="$pass" --text "Enter password for $net")"
        if [ "$?" -ne 0 ]; then
            return 1
        fi
        pass="$p"
    done
    echo "$p"
}

function get_net() {
    local cmd=("${NMCLI[@]}" list)

    [ "$1" = '-r' ] && cmd+=(--rescan yes)
    readarray -t NET <<< "$("${cmd[@]}" | awk '!w[$1]++' | tail +2)"
}

function connect() {
    local cmd=("${NMCLI[@]}" connect "$1")
    local pass

    [[ "$2" -ge 2 ]] && return 1
    "${cmd[@]}"
    case "$?" in
        0)
            ;;
        4) # Connection activation failed.
            while [ "$?" = 4 ]; do
                pass="$(ask_pass "$1")"
                if [ -z "$pass" ]; then
                    exit
                fi
                "${cmd[@]}" password "$pass"
            done
            ;;
        10) # Connection, device, or access point does not exist.
            get_net -r && connect "$@" "$(($2 + 1))"
            ;;
        *)
            return 1
            ;;
    esac
    kill -36 "$(cat "$HOME/.cache/pidofbar")"
    exit
}

function readopt() {
    if ! printf '%s\n' "${NET[@]}" rescan | dmenu -i -l 10; then
        exit
    fi
}

if [ -n "$1" ]; then
    connect "$1"
    exit
fi

get_net
while true; do
    opt="$(readopt)"
    case "$opt" in
        rescan)
            get_net -r
            ;;
        *)
            connect "$(awk '{print $1}' <<< "$opt")"
            ;;
    esac
done
