#!/bin/bash
################################################################################
# Copyright 2026 ModalAI Inc.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors
#    may be used to endorse or promote products derived from this software
#    without specific prior written permission.
#
# 4. The Software is used solely in conjunction with devices provided by
#    ModalAI Inc.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
################################################################################

UTIL_NAME="voxl-wifi"
DEFAULT_SSID="SSID"
DEFAULT_PASS="1234567890"
PLATFORM=$(voxl-platform)
conf_file=wpa_supplicant.conf
wifi_setup_dir=/data/misc/wifi
hostapd_conf_file=/data/misc/wifi/hostapd.conf
# wpa_supplicant_conf_file=/data/misc/wifi/wpa_supplicant.conf
station_interface_file=/data/misc/wifi/station_interface
softap_interface_file=/data/misc/wifi/softap_interface
mode_file=/data/misc/wifi/wlan_mode
station_ssid_file=/data/misc/wifi/station_ssid
softap_ssid_file=/data/misc/wifi/softap_ssid
softap_pass_file=/data/misc/wifi/softap_pass

USER=$(whoami)

# Interface variables (set by detect_wifi_interfaces)
AP_INTERFACE=""
STA_INTERFACE=""
SUPPORTS_CONCURRENT=false

# NetworkManager detection (set by check_networkmanager)
USE_NETWORKMANAGER=false

# Connection names for NetworkManager
NM_STATION_CON="voxl-station"
NM_SOFTAP_CON="voxl-softap"


# Clean up stale legacy configurations that might conflict with NetworkManager
cleanup_legacy_configs() {
	echo "Cleaning up stale legacy configurations..."

	# NOTE: Do NOT touch wpa_supplicant at all - NM manages it via D-Bus!
	# Referencing wpa_supplicant@.service template causes D-Bus name conflicts

	# Stop hostapd/dnsmasq - NM handles hotspot internally
	systemctl stop hostapd 2>/dev/null || true
	systemctl stop dnsmasq 2>/dev/null || true
	systemctl stop voxl-softap 2>/dev/null || true

	systemctl disable hostapd 2>/dev/null || true
	systemctl disable dnsmasq 2>/dev/null || true
	systemctl disable voxl-softap 2>/dev/null || true

	# Remove systemd-networkd configs created by legacy mode
	rm -f /etc/systemd/network/10-wifi.network
	rm -f /etc/systemd/network/20-uap0.network
	rm -f /etc/systemd/network/40-ap.network

	# Reload networkd config (don't restart - that can disrupt networking)
	systemctl reload systemd-networkd 2>/dev/null || true
}


# Check if NetworkManager is installed and ensure it's running
# This normalizes the system state so the tool behaves predictably
check_networkmanager() {
	if command -v nmcli &>/dev/null; then
		# NetworkManager is installed - ensure it's enabled and running
		if ! systemctl is-active --quiet NetworkManager; then
			echo "NetworkManager installed but not running, enabling it..."
			systemctl enable --now NetworkManager 2>/dev/null || true
			# Give NM a moment to start and scan for devices
			sleep 2
		fi

		# Verify it's now running
		if systemctl is-active --quiet NetworkManager; then
			USE_NETWORKMANAGER=true
			echo "NetworkManager detected, using nmcli"
			# Clean up any stale legacy configs that might interfere
			cleanup_legacy_configs
		else
			echo "WARNING: Failed to start NetworkManager, falling back to legacy mode"
		fi
	else
		echo "NetworkManager not installed, using legacy wpa_supplicant/hostapd"
	fi
}


# Detect available WiFi interfaces and concurrency capability
detect_wifi_interfaces() {
	# 1) Check for STA+AP capable interfaces (common on some chipsets)
	if [[ -d /sys/class/net/uap0 && -d /sys/class/net/mlan0 ]]; then
		AP_INTERFACE="uap0"
		STA_INTERFACE="mlan0"
		SUPPORTS_CONCURRENT=true
		echo "Detected concurrent-capable WiFi: AP=$AP_INTERFACE, STA=$STA_INTERFACE"
		return 0
	fi

	# Helper: is this interface actually wireless?
	is_wireless_if() {
		local ifn="$1"
		[[ -d "/sys/class/net/$ifn/wireless" ]] && return 0
		[[ -e "/sys/class/net/$ifn/phy80211" ]] && return 0
		return 1
	}

	# 2) Prefer wlan0 if it exists and is wireless
	if [[ -d /sys/class/net/wlan0 ]] && is_wireless_if wlan0; then
		AP_INTERFACE="wlan0"
		STA_INTERFACE="wlan0"
		echo "Detected WiFi interface: $AP_INTERFACE"
		return 0
	fi

	# 3) Otherwise pick the first "wl*" interface that is actually wireless.
	# This will catch wlx<MAC> names (and other wl* names).
	local ifn
	for ifn in $(ls /sys/class/net 2>/dev/null | sort); do
		[[ "$ifn" == wl* ]] || continue
		is_wireless_if "$ifn" || continue
		AP_INTERFACE="$ifn"
		STA_INTERFACE="$ifn"
		echo "Detected WiFi interface: $AP_INTERFACE"
		return 0
	done

	echo "No WiFi interface detected"
	exit 1
}


print_usage () {
	echo "Description:"
	echo "        Configure the Wi-Fi mode."
	echo ""
	echo "Usage:"
	echo "  ${UTIL_NAME} getmode"
	echo "        Print the current mode (softap, station, sta+ap, or disabled)"
	echo ""
	echo "  ${UTIL_NAME} dump"
	echo "        dump state of all relevant network services to a log file for debug"
	echo ""
	echo "  ${UTIL_NAME} enable-station <ssid> [password]"
	echo "        Enable station mode (concurrent with existing AP if hardware supports it)"
	echo "        If password is omitted, assumes open network"
	echo ""
	echo "  ${UTIL_NAME} enable-softap <ssid> [password] [2ghz|5ghz]"
	echo "        Enable softap mode (concurrent with existing station if hardware supports it)"
	echo "        Band defaults to 5ghz. Password defaults to '${DEFAULT_PASS}'"
	echo ""
	echo "  ${UTIL_NAME} disable-station"
	echo "        Disable station mode only"
	echo ""
	echo "  ${UTIL_NAME} disable-softap"
	echo "        Disable softap mode only"
	echo ""
	echo "  ${UTIL_NAME} disable-all"
	echo "        Disable all WiFi modes"
	echo ""
	exit 0
}


function getmode() {
	if ! [ -f $mode_file ]; then
		echo "unknown wifi mode"
		return 0
	fi

	MODE=$(cat $mode_file)

	if [ $MODE == "station" ]; then
		if [ -f  $station_ssid_file ];then
			ssid=$(cat $station_ssid_file)
			echo "station mode ssid: $ssid"
		fi

	elif [ $MODE == "softap" ]; then

		if [ -f $softap_ssid_file ]; then
			ssid=$(cat $softap_ssid_file)
			echo "softap mode ssid: $ssid"
		fi

		if [ -f $softap_pass_file ]; then
			pass=$(cat $softap_pass_file)
			echo "softap mode pass: $pass"
		fi


	elif [ $MODE == "sta+ap" ]; then
		if [ -f  $station_ssid_file ];then
			ssid=$(cat $station_ssid_file)
			echo "station mode ssid: $ssid"
		fi
		if [ -f $softap_ssid_file ]; then
			ssid=$(cat $softap_ssid_file)
			echo "softap mode ssid: $ssid"
		fi
		if [ -f $softap_pass_file ]; then
			pass=$(cat $softap_pass_file)
			echo "softap mode pass: $pass"
		fi

	else
		## usually "disabled" if we got here
		echo $MODE
	fi

	return 0
}


dump_wifi_state() {
	local tag="$1"
	local ts
	ts="$(date -u +%Y%m%dT%H%M%SZ)"

	local f="/tmp/wifi_state_${tag}_${ts}.log"
	{
		echo "=== ${tag} @ ${ts} ==="
		echo "AP_INTERFACE=${AP_INTERFACE} STA_INTERFACE=${STA_INTERFACE}"
		echo "USE_NETWORKMANAGER=${USE_NETWORKMANAGER}"
		echo

		echo "## processes"
		ps -ef | egrep 'wpa_supplicant|hostapd|dnsmasq|systemd-networkd|NetworkManager|dhclient' | grep -v egrep || true
		echo

		echo "## systemd units"
		systemctl --no-pager -l status NetworkManager 2>/dev/null || true
		systemctl --no-pager -l status "wpa_supplicant@${STA_INTERFACE}.service" 2>/dev/null || true
		systemctl --no-pager -l status hostapd 2>/dev/null || true
		systemctl --no-pager -l status dnsmasq 2>/dev/null || true
		systemctl --no-pager -l status systemd-networkd 2>/dev/null || true
		systemctl --no-pager -l status systemd-resolved 2>/dev/null || true
		echo

		echo "## NetworkManager status"
		if command -v nmcli &>/dev/null; then
			nmcli general status 2>/dev/null || true
			echo
			nmcli device status 2>/dev/null || true
			echo
			nmcli connection show 2>/dev/null || true
			echo
			nmcli connection show "$NM_STATION_CON" 2>/dev/null || echo "(no voxl-station connection)"
			nmcli connection show "$NM_SOFTAP_CON" 2>/dev/null || echo "(no voxl-softap connection)"
		else
			echo "nmcli not available"
		fi
		echo

		echo "## wpa status"
		wpa_cli -i "${STA_INTERFACE}" status 2>/dev/null || true
		wpa_cli -i "${STA_INTERFACE}" signal_poll 2>/dev/null || true
		echo

		echo "## link + addr"
		ip -d link show "${STA_INTERFACE}" 2>/dev/null || true
		ip -4 addr show dev "${STA_INTERFACE}" 2>/dev/null || true
		ip -4 addr show dev usb0 2>/dev/null || true
		echo

		echo "## routes"
		ip route show
		echo
		ip route get 8.8.8.8 2>/dev/null || true
		echo

		echo "## networkd view"
		networkctl status "${STA_INTERFACE}" 2>/dev/null || true
		networkctl status usb0 2>/dev/null || true
		echo

		echo "## resolved view"
		resolvectl status 2>/dev/null || true
		echo

		echo "## recent logs"
		journalctl --no-pager -n 60 -u NetworkManager 2>/dev/null || true
		journalctl --no-pager -n 60 -u "wpa_supplicant@${STA_INTERFACE}.service" 2>/dev/null || true
		journalctl --no-pager -n 60 -u systemd-networkd 2>/dev/null || true
	} >"$f"

	echo "Wrote $f"
	cat $f
}


# Stop all WiFi services
function stop_wlan () {
	stop_station
	stop_softap
}


################################################################################
## NetworkManager-based functions
################################################################################

# Stop station mode using NetworkManager
function stop_station_nm () {
	echo "Stopping station mode (NetworkManager)..."

	# Stop and delete the station connection
	nmcli connection down "$NM_STATION_CON" 2>/dev/null || true
	nmcli connection delete "$NM_STATION_CON" 2>/dev/null || true

	# NOTE: Don't touch wpa_supplicant at all - NM manages it via D-Bus

	# Clean up station files
	rm -f $station_ssid_file
	rm -f $station_interface_file

	# Update mode tracking
	if $SUPPORTS_CONCURRENT; then
		if [ -f $mode_file ] && grep -q "sta+ap" $mode_file; then
			echo "softap" > $mode_file
		elif [ -f $mode_file ] && grep -q "softap" $mode_file; then
			: # keep softap mode
		else
			echo "disabled" > $mode_file
		fi
	else
		echo "disabled" > $mode_file
	fi
}


# Wait for NM to recognize a wifi device as ready
wait_for_nm_device() {
	local iface="$1"
	local max_wait=15
	local count=0

	echo "Waiting for NetworkManager to recognize $iface..."

	# Ensure interface is up at the kernel level
	ip link set "$iface" up 2>/dev/null || true

	while [ $count -lt $max_wait ]; do
		# Check if NM sees the device
		local state=$(nmcli -t -f DEVICE,STATE device status 2>/dev/null | grep "^${iface}:" | cut -d: -f2)

		# If device is unmanaged, tell NM to manage it
		if [ "$state" == "unmanaged" ]; then
			echo "Device $iface is unmanaged, setting to managed..."
			nmcli device set "$iface" managed yes 2>/dev/null || true
			sleep 1
			((count++))
			continue
		fi

		# If device is unavailable, try bringing it up again
		if [ "$state" == "unavailable" ]; then
			ip link set "$iface" up 2>/dev/null || true
			sleep 1
			((count++))
			continue
		fi

		# Device is in a usable state
		if [ -n "$state" ]; then
			echo "Device $iface is ready (state: $state)"
			return 0
		fi

		sleep 1
		((count++))
	done

	# Last resort: show device status for debugging
	echo "WARNING: Device $iface may not be fully ready after ${max_wait}s"
	echo "Current device status:"
	nmcli device status 2>/dev/null || true
	return 1
}


# Enable station mode using NetworkManager
function enable_station_nm () {
	local station_ssid="$1"
	local station_key="$2"

	echo "Enabling station mode on $STA_INTERFACE using NetworkManager..."

	# Stop any existing station connection
	stop_station_nm

	# Stop softap if not concurrent
	if ! $SUPPORTS_CONCURRENT; then
		stop_softap_nm
	fi

	# Stop legacy services (but NOT wpa_supplicant - NM needs it via D-Bus!)
	systemctl disable --now hostapd 2>/dev/null || true

	# Delete any existing wifi connections on this interface that might interfere
	# (keeps other connection types like ethernet intact)
	for conn in $(nmcli -t -f NAME,TYPE connection show | grep ':.*wireless' | cut -d: -f1); do
		if [ "$conn" != "$NM_STATION_CON" ] && [ "$conn" != "$NM_SOFTAP_CON" ]; then
			echo "Removing stale wifi connection: $conn"
			nmcli connection delete "$conn" 2>/dev/null || true
		fi
	done

	# Wait for device to be ready
	wait_for_nm_device "$STA_INTERFACE"

	# Trigger a wifi scan so NM knows about available networks
	nmcli device wifi rescan ifname "$STA_INTERFACE" 2>/dev/null || true
	sleep 1

	# Create the connection profile
	if [ -n "$station_key" ]; then
		nmcli connection add type wifi con-name "$NM_STATION_CON" \
			ifname "$STA_INTERFACE" \
			ssid "$station_ssid" \
			wifi-sec.key-mgmt wpa-psk \
			wifi-sec.psk "$station_key" \
			connection.autoconnect yes \
			connection.interface-name "$STA_INTERFACE"
	else
		# Open network (no password)
		nmcli connection add type wifi con-name "$NM_STATION_CON" \
			ifname "$STA_INTERFACE" \
			ssid "$station_ssid" \
			connection.autoconnect yes \
			connection.interface-name "$STA_INTERFACE"
	fi

	# Bring up the connection explicitly on the correct interface
	nmcli connection up "$NM_STATION_CON" ifname "$STA_INTERFACE"

	# Store station SSID and interface for status display
	echo "${station_ssid}" > ${station_ssid_file}
	echo "${STA_INTERFACE}" > $station_interface_file

	# Update mode tracking
	if $SUPPORTS_CONCURRENT; then
		if [ -f $mode_file ] && grep -q "softap" $mode_file; then
			echo "sta+ap" > $mode_file
		else
			echo "station" > $mode_file
		fi
	else
		echo "station" > $mode_file
	fi

	sync
}


# Stop softap mode using NetworkManager
function stop_softap_nm () {
	echo "Stopping softap mode (NetworkManager)..."

	# Stop and delete the softap connection
	nmcli connection down "$NM_SOFTAP_CON" 2>/dev/null || true
	nmcli connection delete "$NM_SOFTAP_CON" 2>/dev/null || true

	# Also stop any legacy services that might be running
	systemctl disable --now hostapd 2>/dev/null || true
	systemctl disable --now dnsmasq 2>/dev/null || true
	systemctl disable --now voxl-softap 2>/dev/null || true

	# Clean up softap files
	rm -f $softap_interface_file
	rm -f $softap_ssid_file
	rm -f $softap_pass_file

	# Update mode tracking
	if $SUPPORTS_CONCURRENT; then
		if [ -f $mode_file ] && grep -q "sta+ap" $mode_file; then
			echo "station" > $mode_file
		elif [ -f $mode_file ] && grep -q "station" $mode_file; then
			: # keep station mode
		else
			echo "disabled" > $mode_file
		fi
	else
		echo "disabled" > $mode_file
	fi
}


# Enable softap mode using NetworkManager
function enable_softap_nm () {
	local ssid="$1"
	local softap_pass="$2"
	local band="$3"

	echo "Enabling softap mode on $AP_INTERFACE using NetworkManager (band: $band)..."

	# Stop any existing softap connection
	stop_softap_nm

	# Stop station if not concurrent
	if ! $SUPPORTS_CONCURRENT; then
		stop_station_nm
	fi

	# Stop legacy services (but NOT wpa_supplicant - NM needs it via D-Bus!)
	systemctl disable --now hostapd 2>/dev/null || true
	systemctl disable --now dnsmasq 2>/dev/null || true
	systemctl disable --now voxl-softap 2>/dev/null || true

	# Wait for device to be ready
	wait_for_nm_device "$AP_INTERFACE"

	# Determine wifi band and channel
	local wifi_band="bg"
	local channel="6"
	if [ "$band" == "5ghz" ]; then
		wifi_band="a"
		channel="149"
	fi

	# Configure dnsmasq for NM's shared mode to use our preferred DHCP range
	mkdir -p /etc/NetworkManager/dnsmasq-shared.d
	cat > /etc/NetworkManager/dnsmasq-shared.d/voxl-softap.conf << EOF
# VOXL SoftAP DHCP configuration
dhcp-range=192.168.8.10,192.168.8.100,255.255.255.0,24h
dhcp-option=option:router,192.168.8.1
dhcp-option=option:dns-server,192.168.8.1
dhcp-sequential-ip
EOF

	# Clear old DHCP leases so clients get fresh IPs starting at .10
	rm -f /var/lib/NetworkManager/dnsmasq-*.leases

	# Reload NM to pick up the new dnsmasq config
	nmcli general reload conf 2>/dev/null || true

	# Create the hotspot connection with specific IP address
	nmcli connection add type wifi con-name "$NM_SOFTAP_CON" \
		ifname "$AP_INTERFACE" \
		ssid "$ssid" \
		wifi.mode ap \
		wifi.band "$wifi_band" \
		wifi.channel "$channel" \
		wifi-sec.key-mgmt wpa-psk \
		wifi-sec.psk "$softap_pass" \
		ipv4.method shared \
		ipv4.addresses 192.168.8.1/24 \
		connection.autoconnect yes \
		connection.interface-name "$AP_INTERFACE"

	# Bring up the connection explicitly on the correct interface
	nmcli connection up "$NM_SOFTAP_CON" ifname "$AP_INTERFACE"

	# Store softap info for status display
	echo "${AP_INTERFACE}" > $softap_interface_file
	echo "$ssid" > $softap_ssid_file
	echo "$softap_pass" > $softap_pass_file

	# Update mode tracking
	if $SUPPORTS_CONCURRENT; then
		if [ -f $mode_file ] && grep -q "station" $mode_file; then
			echo "sta+ap" > $mode_file
		else
			echo "softap" > $mode_file
		fi
	else
		echo "softap" > $mode_file
	fi

	# Enable IP forwarding for NAT
	echo 1 > /proc/sys/net/ipv4/ip_forward

	sync
}


################################################################################
## Legacy wpa_supplicant/hostapd functions
################################################################################

function stop_station_legacy () {
	# Stop station mode services (both old and new style)
	systemctl disable wpa_supplicant 2>/dev/null >/dev/null
	systemctl stop wpa_supplicant 2>/dev/null >/dev/null

	systemctl disable wpa_supplicant@${STA_INTERFACE}.service 2>/dev/null >/dev/null
	systemctl stop wpa_supplicant@${STA_INTERFACE}.service 2>/dev/null >/dev/null

	# Clean up station files
	rm -f $station_ssid_file
	rm -f $station_interface_file


	# Flush station interface if it exists
	if [ -d /sys/class/net/$STA_INTERFACE ]; then
		ip link set $STA_INTERFACE down 2>/dev/null
		ip addr flush dev $STA_INTERFACE 2>/dev/null
		ip link set $STA_INTERFACE up 2>/dev/null
	fi

	if $SUPPORTS_CONCURRENT; then
		if [ -f $mode_file ] && grep -q "sta+ap" $mode_file; then
			echo "assuming softap mode is still active, just stopping station"
			echo "softap" > $mode_file
		elif [ -f $mode_file ] && grep -q "softap" $mode_file; then
			echo "assuming softap mode is still active"
		else
			echo "disabled" > $mode_file
		fi
	else
		echo "disabled" > $mode_file
	fi
}


function enable_station_legacy () {
	station_ssid="$2"
	station_key="$3"

	stop_station_legacy
	if ! $SUPPORTS_CONCURRENT; then
		echo "stopping softap mode"
		stop_softap_legacy
	fi



	## disable NetworkManager if it exists, we are going to do everything ourselves
	systemctl cat NetworkManager.service >/dev/null 2>&1 && systemctl disable --now NetworkManager.service || true

	echo "Enabling station mode on $STA_INTERFACE (legacy)..."
	echo "creating wpa_supplicant configuration for station mode"

	# obscure the passphrase as a key
	PSK=$(wpa_passphrase "$station_ssid" "$station_key" | sed '/#psk=/d')
	wpa_supplicant_conf_file=/etc/wpa_supplicant/wpa_supplicant-${STA_INTERFACE}.conf

	cat > ${wpa_supplicant_conf_file} << EOF2
ctrl_interface=/var/run/wpa_supplicant
update_config=0
${PSK}

EOF2


	# Store station SSID and interface for status display and mismatch detection
	echo "${station_ssid}" > ${station_ssid_file}
	echo "${STA_INTERFACE}" > $station_interface_file

	sync



	systemctl enable wpa_supplicant@${STA_INTERFACE}.service 2>/dev/null >/dev/null
	systemctl start wpa_supplicant@${STA_INTERFACE}.service 2>/dev/null >/dev/null

	# systemd-resolved doesn't play well with concurrent softap/station modes, disable it
	systemctl disable --now systemd-resolved 2>/dev/null >/dev/null
	rm -f /etc/resolv.conf
	cat > /etc/resolv.conf <<EOF
nameserver 1.1.1.1
nameserver 8.8.8.8
EOF


		## in concurrent mode, stop dhcpcd from interfering
	if $SUPPORTS_CONCURRENT; then
		cat > /etc/systemd/network/20-uap0.network << EOF2
[Match]
Name=uap0

[Network]
Address=192.168.8.1/24
ConfigureWithoutCarrier=yes
DHCP=no

[DHCPv4]
UseRoutes=no
UseDNS=no


EOF2
		DHCPCD_CONF="/etc/dhcpcd.conf"
		LINE="denyinterfaces uap0"
		grep -qxF "$LINE" "$DHCPCD_CONF" || echo "$LINE" >> "$DHCPCD_CONF"
		systemctl enable --now dhcpcd
	fi


	# Update mode tracking
	if $SUPPORTS_CONCURRENT; then
		if [ -f $mode_file ] && grep -q "softap" $mode_file; then
			echo "assuming softap is still active and we are going into dual mode"
			echo "sta+ap" > $mode_file
		else
			echo "station" > $mode_file
		fi
	else
		echo "station" > $mode_file
	fi
	sync
}






function stop_softap_legacy () {
	# Stop softap mode services
	systemctl disable dnsmasq 2>/dev/null >/dev/null
	systemctl stop dnsmasq 2>/dev/null >/dev/null

	systemctl disable hostapd 2>/dev/null >/dev/null
	systemctl stop hostapd 2>/dev/null >/dev/null

	systemctl stop voxl-softap 2>/dev/null >/dev/null
	systemctl disable voxl-softap 2>/dev/null >/dev/null

	# remove any old hostapd interface files
	rm -f /data/misc/wifi/hostapd/wlan0
	rm -f /data/misc/wifi/hostapd/uap0
	rm -f /etc/systemd/network/40-ap.network
	rm -f $softap_interface_file
	rm -f $softap_ssid_file
	rm -f $softap_pass_file

	# Update mode tracking
	if $SUPPORTS_CONCURRENT; then
		if [ -f $mode_file ] && grep -q "sta+ap" $mode_file; then
			echo "assuming station mode is still active, just stopping softap"
			echo "station" > $mode_file
		elif [ -f $mode_file ] && grep -q "station" $mode_file; then
			echo "assuming station mode is still active"
		else
			echo "disabled" > $mode_file
		fi
	else
		echo "disabled" > $mode_file
	fi
}




function enable_softap_legacy () {
	ssid="$2"
	softap_pass="${3:-$DEFAULT_PASS}"
	band="${4:-5ghz}"

	echo "Enabling softap mode on $AP_INTERFACE for band $band (legacy)"

	## disable NetworkManager if it exists, we are going to do everything ourselves
	systemctl cat NetworkManager.service >/dev/null 2>&1 && systemctl disable --now NetworkManager.service || true

	# Disable and flush existing softap setup
	stop_softap_legacy
	if ! $SUPPORTS_CONCURRENT; then
		echo "stopping station mode"
		stop_station_legacy
	fi


	## in concurrent mode, stop dhcpcd from interfering
	if $SUPPORTS_CONCURRENT; then
		cat > /etc/systemd/network/20-uap0.network << EOF2
[Match]
Name=uap0

[Network]
Address=192.168.8.1/24
ConfigureWithoutCarrier=yes
DHCP=no

[DHCPv4]
UseRoutes=no
UseDNS=no

EOF2
		DHCPCD_CONF="/etc/dhcpcd.conf"
		LINE="denyinterfaces uap0"
		grep -qxF "$LINE" "$DHCPCD_CONF" || echo "$LINE" >> "$DHCPCD_CONF"
	fi


	if [ "$band" == "2ghz" ]; then
		cp -f /usr/share/modalai/system-tweaks/hostapd_2ghz ${hostapd_conf_file}
	else
		# Use minimal 5GHz config for uap0 (no advanced features)
		if [ "$SUPPORTS_CONCURRENT" == "true" ]; then
			cp -f /usr/share/modalai/system-tweaks/hostapd_5ghz_uap0 ${hostapd_conf_file}
		else
			cp -f /usr/share/modalai/system-tweaks/hostapd_5ghz_ac ${hostapd_conf_file}
		fi
	fi

	# configure hostapd conf file with ssid and interface
	echo "editing ${hostapd_conf_file} for softap mode, ssid is: ${ssid}, interface: ${AP_INTERFACE}"
	sed -i "/^ssid=/c\ssid=${ssid}" ${hostapd_conf_file}
	sed -i "/^wpa_passphrase=/c\wpa_passphrase=${softap_pass}" ${hostapd_conf_file}
	sed -i "/^interface=/c\interface=${AP_INTERFACE}" ${hostapd_conf_file}

	# Store softap interface for mismatch detection
	echo "${AP_INTERFACE}" > $softap_interface_file
	echo "$ssid" > $softap_ssid_file
	echo "$softap_pass" > $softap_pass_file

	sync

	echo "Enabling voxl-softap service, this may take a bit"
	systemctl enable voxl-softap 2>/dev/null >/dev/null
	systemctl start voxl-softap 2>/dev/null >/dev/null

	# Update mode tracking
	if $SUPPORTS_CONCURRENT; then
		if [ -f $mode_file ] && grep -q "station" $mode_file; then
			echo "assuming station mode is still active and we are going into dual mode"
			echo "sta+ap" > $mode_file
		else
			echo "softap" > $mode_file
		fi
	else
		echo "softap" > $mode_file
	fi
}


################################################################################
## Wrapper functions that dispatch based on NetworkManager availability
################################################################################

function stop_station () {
	if $USE_NETWORKMANAGER; then
		stop_station_nm
	else
		stop_station_legacy
	fi
}

function enable_station () {
	if $USE_NETWORKMANAGER; then
		enable_station_nm "$2" "$3"
	else
		enable_station_legacy "$@"
	fi
}

function stop_softap () {
	if $USE_NETWORKMANAGER; then
		stop_softap_nm
	else
		stop_softap_legacy
	fi
}

function enable_softap () {
	if $USE_NETWORKMANAGER; then
		enable_softap_nm "$2" "${3:-$DEFAULT_PASS}" "${4:-5ghz}"
	else
		enable_softap_legacy "$@"
	fi
}


################################################################################
## actual start of execution
################################################################################

if [ $# -eq 0 ]; then
	print_usage
	exit 1
fi

# print help message if requested
if [ $1 == "-h" ] ||  [ $1 == "--help" ]; then
	print_usage
	exit 0
fi


# sanity checks
if [ "${USER}" != "root" ]; then
	echo "Run this script as the root user"
	exit 1
fi


# simple modes
if [ $1 == "getmode" ]; then
	getmode
	exit 0

elif [ "$1" == "dump" ]; then
	dump_wifi_state
	exit 0
fi


## scan for interfaces before doing real work
mkdir -p $wifi_setup_dir
detect_wifi_interfaces
check_networkmanager

if [ "$1" == "enable-station" ]; then
	if [[ $# -lt 3 ]]; then
		echo "${UTIL_NAME} enable-station: missing ssid and/or passkey"
		exit 1
	fi
	enable_station $@
	echo "Station mode enabled on $STA_INTERFACE"

elif [ "$1" == "enable-softap" ]; then
	if [[ $# -lt 2 ]]; then
		echo "${UTIL_NAME} enable-softap: missing ssid argument"
		exit 1
	fi
	enable_softap $@
	echo "SoftAP mode enabled on $AP_INTERFACE"

elif [ "$1" == "disable-station" ]; then
	echo "Disabling station mode..."
	stop_station

	echo "Station mode disabled"

elif [ "$1" == "disable-softap" ]; then
	echo "Disabling softap mode..."
	stop_softap
	echo "SoftAP mode disabled"

elif [ "$1" == "disable-all" ]; then
	echo "Disabling all WiFi modes..."
	stop_wlan
	echo "disabled" > $wifi_setup_dir/wlan_mode

else
	echo "Illegal command: $1"
	print_usage
	exit 1
fi

sync
