#!/bin/bash

# Try to find the interface that uses the smsc95xx driver
DOODLE_IFACE=$(for iface in $(ls /sys/class/net); do
    driver=$(ethtool -i "$iface" 2>/dev/null | awk '/driver:/ {print $2}')
    if [ "$driver" = "smsc95xx" ]; then
        echo "$iface"
        break
    fi
done)

# Fallback if not found
if [ -z "$DOODLE_IFACE" ]; then
    DOODLE_IFACE="eth0"
fi

#echo "Selected interface: $DOODLE_IFACE"

#
# Get the IP address of VOXL on the Doodle network
#
_get_ethX_ip() {
    # Run ifconfig and get the output
    IFCONFIG_OUTPUT=$(ifconfig)

    # Extract the MAC address of ethX
    IP_ADDR=$(echo "$IFCONFIG_OUTPUT" | grep -A 2 "$DOODLE_IFACE"  | grep 'inet' | awk '{print $2}')

    echo "$IP_ADDR"
}

#
# Get the IP address for the wlan0 interface, derived from MAC address
# of the USB-to-ethernet interface
#
_get_wlan0_ip() {
    # Run ifconfig and get the output
    IFCONFIG_OUTPUT=$(ifconfig)

    # Extract the MAC address of ethX
    MAC_ADDRESS=$(echo "$IFCONFIG_OUTPUT" | grep -A 3 "$DOODLE_IFACE" | grep 'ether' | awk '{print $2}')

    # Check if MAC_ADDRESS is empty
    if [ -z "$MAC_ADDRESS" ]; then
        echo "[ERROR] $DOODLE_IFACE interface not found"
        exit 1
    fi

    # Extract the last two octets of the MAC address
    OCTET5=$(echo $MAC_ADDRESS | cut -d ':' -f 5)
    OCTET6=$(echo $MAC_ADDRESS | cut -d ':' -f 6)

    # Convert hex to decimal
    DEC_OCTET5=$((16#$OCTET5))
    DEC_OCTET6=$((16#$OCTET6))

    #
    # The following is not obvious
    # We decrement the last octet by 0x03 --> from Doodle Labs, this is OK and Safe to use to find wlan0 MAC
    #
    DEC_OCTET6=$((DEC_OCTET6 - 3))

    # Ensure the decremented value is non-negative
    if [ $DEC_OCTET6 -lt 0 ]; then
        DEC_OCTET6=0
    fi

    # Format the IP address
    IP_ADDRESS="10.223.$DEC_OCTET5.$DEC_OCTET6"

    # Print the IP address
    echo "$IP_ADDRESS"
}

#
# Get the FW version of the USB connected doodle radio
#
_get_fw_version() {
    local IP_ADDR="$1"
    local FW_VER=$(ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@"$IP_ADDR" 'cat /etc/banner | grep firmware')
    echo "$FW_VER"
}

#
# Get the mesh ID of the USB connected doodle radio
#
_get_mesh_id() {
    local IP_ADDR="$1"
    local MESH_ID=$(ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@"$IP_ADDR" 'uci show | grep -F simpleconfig.@general[0].mesh_id')
    echo "$MESH_ID"
}

#
# Get the mesh key of the USB connected doodle radio
#
_get_mesh_key() {
    local IP_ADDR="$1"
    local MESH_ID=$(ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@"$IP_ADDR" 'uci show | grep -F simpleconfig.@general[0].password')
    echo "$MESH_ID"
}

#
# Get information about wlan0
#
_get_wlan0_info() {
    local IP_ADDR="$1"
    local MESH_ID=$(ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@"$IP_ADDR" 'iw wlan0 info')
    echo "$MESH_ID"
}

#
# Get information about wlan0
#
_get_wlan0_assoclist() {
    local IP_ADDR="$1"
    local MESH_ID=$(ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@"$IP_ADDR" 'iwinfo wlan0 assoclist')
    echo "$MESH_ID"
}

#
# Set the mesh ID
# using serial number value in -> /sys/devices/soc0/serial_number
#
_set_mesh_id_auto() {
    local IP_ADDR="$1"

    # Read from /sys/devices/soc0/serial_number
    if [ ! -f /sys/devices/soc0/serial_number ]; then
        echo "[ERROR] Unable to find /sys/devices/soc0/serial_number"
        exit 1
    fi
    SERIAL_NUMBER=$(cat /sys/devices/soc0/serial_number)

    if [ -z "$SERIAL_NUMBER" ]; then
        echo "[ERROR] Failed to read value from /sys/devices/soc0/serial_number"
        exit 1
    fi

    NEW_MESH_ID="MESH-$SERIAL_NUMBER"

    ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@"$IP_ADDR" \
        "uci set simpleconfig.@general[0].mesh_id='$NEW_MESH_ID' && uci commit && echo 'Mesh ID updated to $NEW_MESH_ID'"
}

# Command line parsing
if [ "$1" == "-i" ]; then
    IP_ADDR=$(_get_ethX_ip)
    echo "$IP_ADDR"
elif [ "$1" == "-w" ]; then
    IP_ADDR=$(_get_wlan0_ip)
    echo "$IP_ADDR"
elif [ "$1" == "-f" ]; then
    IP_ADDR=$(_get_wlan0_ip)
    FW_VER=$(_get_fw_version $IP_ADDR)
    echo "$FW_VER"
elif [ "$1" == "-m" ]; then
    IP_ADDR=$(_get_wlan0_ip)
    MESH_ID=$(_get_mesh_id $IP_ADDR)
    echo "$MESH_ID"
elif [ "$1" == "-k" ]; then
    IP_ADDR=$(_get_wlan0_ip)
    MESH_KEY=$(_get_mesh_key $IP_ADDR)
    echo "$MESH_KEY"
elif [ "$1" == "-l" ]; then
    IP_ADDR=$(_get_wlan0_ip)
    INFO=$(_get_wlan0_info $IP_ADDR)
    echo "$INFO"
elif [ "$1" == "-a" ]; then
    IP_ADDR=$(_get_wlan0_ip)
    INFO=$(_get_wlan0_assoclist $IP_ADDR)
    echo "$INFO"
elif [ "$1" == "-s" ]; then
    IP_ADDR=$(_get_wlan0_ip)
    _set_mesh_id_auto "$IP_ADDR"
else
    echo "Usage: $0"
    echo "  -i  get VOXL2 IP address on the doodle network for the radio connected over USB"
    echo "  -w  get wlan0 IP address of radio connected over USB"
    echo "  -f  get the FW version of the radio connected over USB"
    echo "  -m  get mesh ID"
    echo "  -k  get mesh key"
    echo "  -l  get information about wlan0"
    echo "  -a  get information about connected mesh nodes"
    echo "  -s  set a new mesh ID using the drone's serial number"
fi
