#!/usr/bin/env bash
# ABOUTME: Walker-dmenu VPN connection manager using NetworkManager (nmcli).
# ABOUTME: Lists VPN/WireGuard connections and toggles them on/off with notifications.

# Based on rofi-vpn by Damien Cassou <damien@cassou.me>
# https://gitlab.com/DamienCassou/rofi-vpn
# Licensed under GPL-3.0-or-later

# Prefixes for active/inactive VPN connections (Nerd Font icons):
ACTIVE_PREFIX="󰌘  "
INACTIVE_PREFIX="󰌙  "

for cmd in nmcli walker; do
    command -v "$cmd" >/dev/null 2>&1 || {
        echo "Error: '$cmd' not found" >&2
        exit 1
    }
done

# List all VPN and WireGuard connections with active/inactive prefix.
function list_vpn_connections() {
    nmcli --get-values ACTIVE,NAME,TYPE connection show \
        | grep -E ':(vpn|wireguard)$' \
        | sed \
              -e "s/^no:/${INACTIVE_PREFIX}/" \
              -e "s/^yes:/${ACTIVE_PREFIX}/" \
              -e 's/:\(vpn\|wireguard\)$//'
}

# Remove the known prefix to extract the bare connection name.
function extract_connection_name() {
    local result="$1"
    result="${result#"$ACTIVE_PREFIX"}"
    result="${result#"$INACTIVE_PREFIX"}"
    echo "$result"
}

# Connect a VPN.
# Requires nm-applet (or another NM secret agent) for interactive auth.
function connect_vpn() {
    local connection="$1"
    nmcli connection up id "$connection"
}

# Disconnect a VPN.
function disconnect_vpn() {
    local connection="$1"
    nmcli connection down id "$connection"
}

# Toggle the VPN connection based on its current state.
function toggle_vpn_connection() {
    local result="$1"
    local connection

    connection=$(extract_connection_name "$result")

    if [[ $result = "${ACTIVE_PREFIX}"* ]]; then
        disconnect_vpn "$connection"
    else
        connect_vpn "$connection"
    fi

    pkill -RTMIN+9 waybar 2>/dev/null
}

# Show the VPN picker using Walker.
function pick_connection() {
    local content="$1"
    echo -e "$content" | walker -d -p "󰖂  VPN"
}

function main() {
    local connections
    local result

    connections=$(list_vpn_connections)

    if [[ -z "$connections" ]]; then
        exit 0
    fi

    result=$(pick_connection "$connections")

    if [[ -n "$result" ]]; then
        toggle_vpn_connection "$result"
    fi
}

main
