#!/usr/bin/env bash
# Network state for the bar icons and the net panel: wifi, ethernet and USB
# tethering.  Refreshes on link/address changes and every 30 s (signal level).

wifi_iface() { awk 'NR > 2 { sub(":", "", $1); print $1; exit }' /proc/net/wireless; }
eth_iface() { ip -o link 2>/dev/null | awk '$2 ~ /^en[op]/ { sub(":", "", $2); print $2; exit }'; }
usb_iface() { ip -o link 2>/dev/null | awk '$2 ~ /^(usb[0-9]|enx)/ { sub(":", "", $2); print $2; exit }'; }
ipv4() { ip -4 -o addr show "$1" 2>/dev/null | awk '{ print $4; exit }'; }

signal_icon() {
  local dbm=${1:-}
  [[ -z $dbm ]] && { echo "󰤮"; return; }
  if ((dbm >= -50)); then echo "󰤨"
  elif ((dbm >= -60)); then echo "󰤥"
  elif ((dbm >= -70)); then echo "󰤢"
  elif ((dbm >= -80)); then echo "󰤟"
  else echo "󰤯"; fi
}

band() {
  local f=${1:-0}
  if ((f >= 5925)); then echo "6 GHz"
  elif ((f >= 4900)); then echo "5 GHz"
  elif ((f >= 2400)); then echo "2.4 GHz"
  else echo ""; fi
}

generation() {
  case ${1:-} in
    7) echo "Wi-Fi 7" ;; 6) echo "Wi-Fi 6" ;; 5) echo "Wi-Fi 5" ;; 4) echo "Wi-Fi 4" ;; *) echo "" ;;
  esac
}

state() {
  local wifi eth usb
  wifi=$(wifi_iface)
  eth=$(eth_iface)
  usb=$(usb_iface)

  local w_enabled=false w_connected=false w_icon="󰤮" w_ssid="" w_ip="" w_freq=0 w_gen="" w_signal=0 wpa
  rfkill list wlan 2>/dev/null | grep -q "Soft blocked: yes" || w_enabled=true
  if [[ -n $wifi ]]; then
    w_ip=$(ipv4 "$wifi")
    if [[ -n $w_ip ]]; then
      w_connected=true
      wpa=$(wpa_cli -g "/run/wpa_supplicant/$wifi" status 2>/dev/null)
      w_ssid=$(awk -F= '/^ssid=/ { print $2; exit }' <<<"$wpa")
      w_freq=$(awk -F= '/^freq=/ { print $2; exit }' <<<"$wpa")
      w_gen=$(generation "$(awk -F= '/^wifi_generation=/ { print $2; exit }' <<<"$wpa")")
      w_signal=$(awk -v i="$wifi:" '$1 == i { sub(/\./, "", $4); print $4; exit }' /proc/net/wireless)
      w_icon=$(signal_icon "$w_signal")
    fi
  fi

  local e_connected=false e_ip="" e_speed="" spd
  if [[ -n $eth ]] && ip -o link show "$eth" 2>/dev/null | grep -q "state UP"; then
    e_connected=true
    e_ip=$(ipv4 "$eth")
    spd=$(cat "/sys/class/net/$eth/speed" 2>/dev/null)
    [[ ${spd:-0} -gt 0 ]] 2>/dev/null && e_speed="${spd} Mbps"
  fi

  local u_connected=false u_ip=""
  if [[ -n $usb ]]; then
    u_ip=$(ipv4 "$usb")
    [[ -n $u_ip ]] && u_connected=true
  fi

  printf '{"wifi":{"connected":%s,"enabled":%s,"icon":"%s","ssid":"%s","ip":"%s","freq":%s,"band":"%s","gen":"%s","signal":%s},' \
    "$w_connected" "$w_enabled" "$w_icon" "$(jstr "$w_ssid")" "$w_ip" "${w_freq:-0}" "$(band "$w_freq")" "$w_gen" "${w_signal:-0}"
  printf '"ethernet":{"connected":%s,"interface":"%s","ip":"%s","speed":"%s"},' \
    "$e_connected" "$eth" "$e_ip" "$e_speed"
  printf '"usb":{"connected":%s,"interface":"%s","ip":"%s"}}' \
    "$u_connected" "$usb" "$u_ip"
}

refresh() { emit "$(state)"; }
_link_events() { exec ip monitor link address; }

refresh
mux_init
mux_add _link_events
mux_tick 30
mux_loop refresh
