#!/bin/bash
# prevents weirdness over tty
export NCURSES_NO_UTF8_ACS=1
export TERM=xterm-256color
export LANG=C.UTF-8

if [[ $EUID -ne 0 ]]; then
  echo "This script must be run as root."
  echo "Try \`sudo femto-config\`."
  exit 1
fi

# pause
pause() {
  echo "Press any key to continue..."
  read -n 1 -s -r
}

loading() {
  dialog --no-collapse --infobox "$1" 5 45
}

## function to pull data from various femto scripts and convert it to the contents of a read only dialog --form
# ingest_form_data() { # usage: `ingest_form_data "command.sh -argument" key_width value_width`
#   unset  output_array #debug code, delete me
#   declare -a output_array
#   # Read the output from femto-meshtasticd-config.sh and store it in the array
#   while IFS=':' read -r key value; do
#     # Trim leading/trailing spaces from key and value
#     key=$(echo "$key" | xargs)
#     value=$(echo "$value" | xargs)
#     output_array+=("$key=$value")  # Use indexed array to preserve order
#   done < <(eval $1)
#   form_contents=""
#   i=1
#   for pair in "${output_array[@]}"; do
#     key=$(cut -d'=' -f1 <<< "$pair")
#     value=$(cut -d'=' -f2- <<< "$pair")
#     form_contents+="\"$key\" $i 1 \"$value\" $i $2 $3 -1 "
#     ((i++))
#   done
#   echo "$form_contents" | sed 's/\x1b\[[0-9;]*m//g'
# }
## CODE TO USE THIS FUNCTION:
# eval "$(echo -e "dialog --no-collapse --no-cancel --form \"Meshtastic node info\" 0 0 0 $(ingest_form_data "femto-meshtasticd-config.sh -i" 18 0) 2>/dev/null")"


# function to pull data from various femto scripts and convert it a simple text string, with dialog colors
ingest_data() { # usage: `ingest_data "command.sh -argument" key_width`
  local output_string=""
  # Read the output from femto-meshtasticd-config.sh and store output_string
  while IFS=':' read -r key value; do
    key=$(femto-utils.sh -R "$(echo "$key")")
    value=$(femto-utils.sh -R "$(echo "$value" | xargs)")    # Trim leading/trailing spaces from value
    if [[ -z "$key" && -z "$value" ]]; then
      output_string+="---\n"
    else
      output_string+=$(printf "%s:%*s%s\n" "$key" $(($2 - 1 - ${#key})) "" "$value\n") # save the key and value to the output_string, adding padding between them as determined by `$2 - 1 - key-length` The 1 accounts for the :
    fi
  done < <(eval $1)
  echo -e "$output_string"
}

check_meshtasticd_running() {
  if ! echo $(femto-utils.sh -C "meshtasticd") | sed 's/\x1b\[[0-9;]*m//g' | grep -q ", running"; then
    dialog --no-collapse --title "Meshtasticd service" --yesno "Meshtasticd service is not running but is required.\n\nStart service?" 9 50
    if [ $? -eq 0 ]; then #unless cancel/no
      femto-meshtasticd-config.sh -s
      echo "Waiting for meshtasticd service to start..."
      sleep 3
      if ! echo $(femto-utils.sh -C "meshtasticd") | sed 's/\x1b\[[0-9;]*m//g' | grep -q ", running"; then
        dialog --no-collapse --colors --title "Meshtasticd service" --msgbox "Meshtasticd service ($(femto-utils.sh -R "$(femto-utils.sh -C "meshtasticd")")) failed to run, but is required." 7 50
        return 1
      fi
      return 0
    else
      return 1
    fi
  fi
}

wifi_config() {
  local title2="Wi-Fi (wlan0) Settings"
  local config=$(dialog --no-collapse --title "$title2" --form "↑ ↓ to navigate, [ESC] to cancel." 10 45 0 \
              "SSID:" 1 1 "$(grep -oP '^ *ssid="\K[^"]+' /etc/wpa_supplicant/wpa_supplicant.conf)" 1 15 24 32\
              "Password:" 2 1 "" 2 15 24 64\
              "Country Code:" 3 1 "$(grep -oP '^ *country=\K[^ ]+' /etc/wpa_supplicant/wpa_supplicant.conf)" 3 15 24 2\
              3>&1 1>&2 2>&3)
  # Parse the output
  wifi_ssid=$(echo "$config" | sed -n '1p')
  wifi_psk=$(echo "$config" | sed -n '2p')
  wifi_country=$(echo "$config" | sed -n '3p')

  cmd="femto-network-config.sh -s \"$wifi_ssid\" -p \"$wifi_psk\"" # build the wifi setting command to send to the network config script
  [ -n "$wifi_country" ] && cmd="$cmd -c \"$wifi_country\""
  cmd="$cmd -r"
  if [ -z "$wifi_ssid" ]; then
    dialog --no-collapse --title "$title2" --msgbox "\nSSID is required to configure Wi-Fi." 7 40
    return
  fi
  echo "Configuring wifi..."
  eval $cmd &>/dev/null
  dialog --no-collapse --title "$title2" --msgbox "Wi-Fi Settings Saved:\nSSID: $wifi_ssid\nPassword: (hidden)\nCountry: $wifi_country\nMeshtastic Wi-Fi setting set to ON" 9 40
  if [ "$1" = "-w" ]; then
    exit 0
  fi
}

# Function to handle Wi-Fi settings
networking_settings() {
  local title="Networking"
  local title2="Wi-Fi (wlan0) Settings"
  wpa_supplicant_conf="/etc/wpa_supplicant/wpa_supplicant.conf"
  choice=""   # zero the choice before loading the submenu
  while true; do
    networking_choice=$(dialog --no-collapse --cancel-label "Back" --backtitle "IPv4 address:  $(femto-network-config.sh -i)" --default-item "$networking_choice" --title "$title" --item-help --menu "" 17 40 4 \
      1 "Turn Wi-Fi on/off" "" \
      2 "View Wi-Fi settings" "" \
      3 "Change Wi-Fi settings" "" \
      4 "View ethernet settings" "" \
      5 "Restart networking" "" \
      6 "Set hostname" "" \
      7 "Test internet connection" "" \
      8 "Manage Meshtastic wifi sync" "" \
      " " "" "" \
      9 "Back to main menu" "" 3>&1 1>&2 2>&3)
    [ $? -eq 1 ] && break # Exit the loop if the user selects "Cancel" or closes the dialog
    case $networking_choice in
      1) # Turn Wi-Fi on/off)
        if ! ip link show wlan0 &>/dev/null; then
          dialog --no-collapse --colors --msgbox "\Z1Network adapter wlan0 does not exist.\Zn\n\nIs a Wi-Fi adapter connected?" 8 40
        else
          while true; do
            choice=$(dialog --no-collapse --cancel-label "Back" --default-item "$choice" --title "Enable/disable Wi-Fi" --item-help --menu "Tip: Wi-Fi can also be toggled by short-pressing the BOOT button on the Luckfox." 13 50 5 \
              1 "Turn Wi-Fi on" "" \
              2 "Turn Wi-Fi off" "" \
              " " "" "" \
              3 "Return to previous menu" "" 3>&1 1>&2 2>&3)
            [ $? -eq 1 ] && break # Exit the loop if the user selects "Cancel" or closes the dialog
            case $choice in
              1) femto-network-config.sh -x "up" && break ;;
              2) femto-network-config.sh -x "down" && break ;;
              3) break ;;
            esac
          done
        fi
      ;;
      2) # View Wi-Fi settings)
        echo "Getting Wi-Fi configuration..."
        dialog --no-collapse --title "$title2" --colors --msgbox "$(ingest_data "femto-network-config.sh -w" 15)" 0 0
      ;;
      3) # Change Wi-Fi settings)
        wifi_config
      ;;
      4) # View ethernet settings)
        echo "Getting ethernet configuration..."
        dialog --no-collapse --title "Ethernet (eth0) settings" --colors --msgbox "$(ingest_data "femto-network-config.sh -e" 15)" 0 0
      ;;
      5) # Restart networking)
        dialog --no-collapse --title "$title2" --yesno "Wi-Fi and Ethernet will be restarted.\nMeshtastic Wi-Fi setting will be set to ON.\n\nProceed?" 10 40
        if [ $? -eq 0 ]; then #unless cancel/no
          femto-network-config.sh -r
        fi
      ;;
      6) # set hostname)
        new_hostname=$(dialog --no-collapse --title "$title" --max-input 253 --inputbox "Enter new hostname:" 8 40 $(hostname) 3>&1 1>&2 2>&3)
        if [ $? -eq 0 ]; then #unless cancel/no
          femto-network-config.sh -n "$new_hostname"
          dialog --no-collapse --title "$title" --msgbox "Femtofox is now reachable at\n$new_hostname.local" 8 40
        fi
      ;;
      7) # Test internet connection)
        loading "Testing internet connection..."
        dialog --no-collapse --title "Internet connectivity test" --colors --msgbox "$(femto-utils.sh -R "$(femto-network-config.sh -t)")" 9 40
      ;;
      8) # Manage Meshtastic wifi sync)
        choice=""   # zero the choice before loading the submenu
        while true; do
          echo "Checking Meshtastic wifi sync service state..."
          local service_state="$(femto-utils.sh -R "$(femto-utils.sh -C "femto-wifi-mesh-control")")"
          choice=$(dialog --no-collapse --colors --help-button --cancel-label "Back" --title "Meshtastic wifi sync Service" --default-item "$choice" --menu "Meshtastic wifi sync service is $service_state" 16 60 5 \
            "View detailed service status" "x" \
            " " "" \
            "Start/restart service" "x" \
            $(if ! echo "$service_state" | grep -q 'not running'; then echo "Stop service x"; fi) \
            " " "" \
            $(if echo "$service_state" | grep -q 'disabled'; then echo "Enable service x"; fi) \
            $(if echo "$service_state" | grep -q 'enabled'; then echo "Disable service x"; fi) \
            " " "" \
            "Back to previous menu" "x" 3>&1 1>&2 2>&3)
          exit_status=$? # This line checks the exit status of the dialog command
          if [ $exit_status -eq 1 ]; then # Exit the loop if the user selects "Cancel" or closes the dialog
            break
          elif [ $exit_status -eq 2 ]; then # Help ("extra") button
            dialog --no-collapse --colors --title "Meshtastic wifi sync service help" --msgbox "The Meshtastic wifi sync service synchronizes system wifi settings with Meshtastic wifi settings. This allows you to use Meshtastic's remote node administration feature to enable/disable wifi.\n\nIn future, this will also allow you to reconfigure SSID and password.\n" 0 0
          else
            case $choice in
              "View detailed service status") 
                echo "Getting Meshtastic wifi sync service status..."
                dialog --no-collapse --title "Meshtastic wifi sync service status" --msgbox "$(systemctl status femto-wifi-mesh-control)" 0 0
              ;;
              "Start/restart service") 
                dialog --no-collapse --title "$title" --yesno "Start/restart Meshtastic wifi sync service?" 7 45
                if [ $? -eq 0 ]; then #unless cancel/no
                  systemctl restart femto-wifi-mesh-control
                  dialog --no-collapse --colors --msgbox "Sent \`\Zusystemctl restart femto-wifi-mesh-control wifi sync\Zn\` command to system.\n\nMeshtastic wifi sync should be running." 10 60
                fi
              ;;
              "Stop service")
                dialog --no-collapse --colors --title "$title" --yesno "Stop Meshtastic wifi sync service?\n\nThis will take the node \Zu\Z1OFFLINE\Zn.\n\nMeshtastic wifi sync will automatically restart on boot service if enabled." 11 50
                if [ $? -eq 0 ]; then #unless cancel/no
                  systemctl stop femto-wifi-mesh-control
                  dialog --no-collapse --colors --msgbox "Sent \`\Zusystemctl stop femto-wifi-mesh-control\Zn\` command to system.\n\nMeshtastic wifi sync should be stopped." 9 60
                fi
              ;;
              "Enable service")
                dialog --no-collapse --title "$title" --yesno "Enable Meshtastic wifi sync service?" 6 45
                if [ $? -eq 0 ]; then #unless cancel/no
                  systemctl enable femto-wifi-mesh-control
                  systemctl start femto-wifi-mesh-control
                  dialog --no-collapse --colors --msgbox "Sent \`\Zusystemctl enable femto-wifi-mesh-control\Zn\` and \`\Zusystemctl start femto-wifi-mesh-control\Zn\` commands to system.\n\nMeshtastic wifi sync should be running." 10 60
                fi
              ;;
              "Disable service")
                dialog --no-collapse --colors --title "$title" --yesno "Disable Meshtastic wifi sync service?\n\nThis will take the node \Zu\Z1OFFLINE\Zn and will not restart!" 9 50
                if [ $? -eq 0 ]; then #unless cancel/no
                  systemctl disable femto-wifi-mesh-control
                  systemctl stop femto-wifi-mesh-control
                  dialog --no-collapse --colors --msgbox "Sent \`\Zusystemctl disable femto-wifi-mesh-control\Zn\` and \`\Zusystemctl stop femto-wifi-mesh-control\Zn\` commands to system.\n\nMeshtastic wifi sync should be disabled and stopped." 10 60
                fi
              ;;
              "Back to previous menu") break ;; 
            esac
          fi
        done
      ;;
      9)
        return
      ;;
    esac
  done
}

# utilities
utilities() {
  local title="Utilities & Tools"
  while true; do
    utilities_choice=$(dialog --no-collapse --cancel-label "Back" --default-item "$utilities_choice" --item-help --menu "$title" 21 50 4 \
      1 "View system info" "" \
      2 "Set system time" "" \
      3 "Kernel module manager" "" \
      4 "Re-run first-boot script" "" \
      5 "Run USB configuration tool" "" \
      6 "Run OEM luckfox-config" "" \
      7 "Process viewer/manager" "" \
      8 "Disable/enable logging" "" \
      9 "Disable/enable activity LED" "" \
      10 "Reboot" "" \
      11 "Shutdown" "" \
      " " "" "" \
      12 "Back to main menu" "" 3>&1 1>&2 2>&3)
    [ $? -eq 1 ] && break # Exit the loop if the user selects "Cancel" or closes the dialog
    
    case $utilities_choice in
      1) #sysinfo)
        sysinfo_choice=""   # zero the choice before loading the submenu
        while true; do
        echo $sysinfo_choice
          sysinfo_choice=$(dialog --no-collapse --help-button --backtitle "$(femto-utils.sh -v)" --cancel-label "Back" --default-item "$sysinfo_choice" --item-help --menu "System info" 17 40 5 \
            1 "Operating system" "" \
            2 "CPU" "" \
            3 "Storage & memory" "" \
            4 "Peripherals & devices" ""\
            5 "Networking" "" \
            6 "Meshtastic node info" "" \
            7 "Complete system info" "" \
            " " "" "" \
            8 "Back to previous menu" "" 3>&1 1>&2 2>&3)
          exit_status=$? # This line checks the exit status of the dialog command
          if [ $exit_status -eq 1 ]; then # Exit the loop if the user selects "Cancel" or closes the dialog
            break
          elif [ $exit_status -eq 2 ]; then # Help ("extra") button
            dialog --no-collapse --colors --title "System info help" --msgbox "To get system info in terminal (where it can be copied), enter \`\Zusudo femto-utils.sh -i\Zn\`.\n\nWhen getting Peripherals & Devices Info (or Complete System Info) without an i2c device connected, it is normal to see error messages on serial console.\n" 0 0
          else
            case $sysinfo_choice in
              1) # Operating system)
                loading "Loading operating system info..."
                dialog --no-collapse --colors --title "Operating system info" --msgbox "$(ingest_data "femto-utils.sh -o" 15)" 0 0
              ;;
              2) # CPU)
                loading "Loading CPU info..."
                dialog --no-collapse --colors --title "CPU info" --msgbox "$(ingest_data "femto-utils.sh -c" 15)" 0 0
              ;;
              3) # Storage & memory)
                loading "Loading storage & memory info..."
                dialog --no-collapse --colors --title "Storage & memory info" --msgbox "$(ingest_data "femto-utils.sh -S" 15)" 0 0
              ;;
              4) # Peripherals & devices)
                loading "Loading peripherals & devices info..."
                dialog --no-collapse --colors --title "Peripherals & devices info" --msgbox "$(ingest_data "femto-utils.sh -p" 15)" 0 0
              ;; 
              5) # Networking)
                loading "Loading networking info..."
                dialog --no-collapse --colors --title "Networking info" --msgbox "$(ingest_data "femto-utils.sh -n" 15)" 0 0
              ;;
              6) # Meshtastic node info)
                check_meshtasticd_running && (
                  loading "Loading Meshtastic node info..."
                  dialog --no-collapse --colors --title "Meshtastic node info" --msgbox "$(ingest_data "femto-meshtasticd-config.sh -i" 15)" 0 0
                )
              ;;
              7) # Complete system info)
                loading "Loading complete system info..."
                dialog --no-collapse --colors --title "Complete system info" --msgbox "$(ingest_data "femto-utils.sh -i" 15)" 0 0
              ;;
              8) break ;;
            esac
          fi
        done
      ;;
      2) femto-set-time.sh ;; # set timezone
      3) # Kernel modules)
        femto-kernel-modules.sh
      ;;
      4) femto-runonce.sh ;; # Re-run first-boot script
      5) # USB config)
        dialog --no-collapse --title "$title" --yesno "The USB configuration tool allows you to set critical Femtofox settings with a text file on a USB flash drive.\n\nFor more information, visit\ngithub.com/femtofox/femtofox/blob/main/usb_config.md\n\nThis tool is run automatically at boot.\n\nRun now?" 14 60
        if [ $? -eq 0 ]; then #unless cancel/no
          femto-usb-config-tool.sh
          pause
        fi
      ;;
      6) luckfox-config ;;
      7) htop ;;
      8) # logging)
        choice=""   # zero the choice before loading the submenu
        while true; do
          echo "Checking current logging status..."
          choice=$(dialog --no-collapse --colors --title "Logging" --cancel-label "Back" --default-item "$choice" --item-help --menu "Before deploying a Femtofox, it is advisable to disable logging to reduce SD card wear.\nCurrent state: $(femto-utils.sh -R "$(femto-utils.sh -l "check")")" 14 50 2 \
            1 "Enable (default)" "" \
            2 "Disable" "" \
            " " "" "" \
            3 "Return to previous menu" "" 3>&1 1>&2 2>&3)
          [ $? -eq 1 ] && break # Exit the loop if the user selects "Cancel" or closes the dialog
          case $choice in
            1) femto-utils.sh -l "enable" ;;
            2) femto-utils.sh -l "disable" ;;
            3) break ;;
          esac
        done
      ;;
      9) # activity LED)
        choice=""   # zero the choice before loading the submenu
        while true; do
          echo "Checking current activity LED status..."
          choice=$(dialog --no-collapse --colors --title "Logging" --cancel-label "Back" --default-item "$choice" --item-help --menu "Before deploying a Femtofox, it is advisable to disable the Activity LED to save power.\nCurrent state: $(femto-utils.sh -R "$(femto-utils.sh -a "check")")" 14 50 2 \
            1 "Enable (default)" "" \
            2 "Disable" "" \
            " " "" "" \
            3 "Return to previous menu" "" 3>&1 1>&2 2>&3)
          [ $? -eq 1 ] && break # Exit the loop if the user selects "Cancel" or closes the dialog
          case $choice in
            1) femto-utils.sh -a "enable" ;;
            2) femto-utils.sh -a "disable" ;;
            3) break ;;
          esac
        done
      ;;
      10) # reboot)
        dialog --no-collapse --title "$title" --yesno "Reboot now?\n\nTip: Reboot can also be triggered by long-pressing the BOOT button on the luckfox." 10 45
        if [ $? -eq 0 ]; then #unless cancel/no
          loading "Rebooting..."
          femto-utils.sh -r
        fi
      ;;
      11) # shutdown)
        dialog --no-collapse --colors --title "$title" --yesno "Shut down now?\n\nTo power system back on, disconnect/reconnect power.\n\nThe system shutdown command prevents damage to the filesystem from power interrupts, but does not stop power consumption.\n\nTip: You can also shut down the Femtofox by pressing the BOOT button for 5 seconds or by running \`\Zusudo halt\Zn\`." 14 60
        if [ $? -eq 0 ]; then #unless cancel/no
          loading "Shutting down...\n\nPower consumption will not stop."
          femto-utils.sh -s
        fi
      ;;
      12) return ;;
    esac
  done
}

legacy_admin() {
  choice=""   # zero the choice before loading the submenu
  while true; do
    loading "Getting current legacy admin state..."
    choice=$(dialog --no-collapse --colors --title "Legacy Admin" --default-item "$choice" --help-button --item-help --menu "If the node you Femtofox needs to administer or be administered by is running 2.4.x or earlier, you should set this to Enabled.\n\nCurrent state: $(femto-utils.sh -R "$(femto-meshtasticd-config.sh -p)")" 16 65 5 \
      1 "Enable" "" \
      2 "Disable (default)" "" \
      " " "" "" \
      3 "Return to previous menu" "" 3>&1 1>&2 2>&3)
    exit_status=$? # This line checks the exit status of the dialog command
    if [ $exit_status -eq 1 ]; then # Exit the loop if the user selects "Cancel" or closes the dialog
      break
    elif [ $exit_status -eq 2 ]; then # Help ("extra") button
      dialog --no-collapse --colors --title "System info help" --msgbox "For Meshtastic versions 2.4.x and earlier, remote admin is achieved by creating a secondary channel named admin with a shared PSK. In this setup, messages exchanged on this channel are encrypted only with the channel's PSK, allowing any node in the channel to administer others.\n\nFor more information:\nhttps://meshtastic.org/docs/configuration/remote-admin/\n" 0 0
    else
      case $choice in
        1) # enable legacy admin)
          dialog --no-collapse --title "Legacy Admin" --yesno "Enable legacy admin channel?\n" 0 0
          if [ $? -eq 0 ]; then #unless cancel/no
            loading "Sending command..."
            dialog --no-collapse --colors --title "Legacy admin" --msgbox "$(femto-meshtasticd-config.sh -o "true" && echo -e "\n\Z4Command successful!\Zn\n" || echo -e "\n\Z1Command failed.\Zn\n")" 0 0
          fi
        ;;
        2) # disable legacy admin)
          dialog --no-collapse --title "Legacy Admin" --yesno "Disable legacy admin channel?\n" 0 0
          if [ $? -eq 0 ]; then #unless cancel/no
            loading "Sending command..."
            dialog --no-collapse --colors --title "Legacy admin" --msgbox "$(femto-meshtasticd-config.sh -o "false" && echo -e "\n\Z4Command successful!\Zn\n" || echo -e "\n\Z1Command failed.\Zn\n")" 0 0
          fi
        ;;
        3) break ;;
      esac
    fi
  done
}

# Function to handle Meshtasticd settings
meshtastic_settings() {
  local title="Meshtastic Settings"
  while true; do
    echo "Checking Meshtasticd service state..."
    meshtastic_choice=$(dialog --no-collapse --colors --title "$title" --cancel-label "Back" --default-item "$meshtastic_choice" --item-help --menu "Meshtasticd service is $(femto-utils.sh -R "$(femto-utils.sh -C "meshtasticd")")$(femto-meshtasticd-config.sh -k | grep -q 'simulated' && echo '\n\Z1Warning: using simulated radio\Zn')" 18 50 4 \
      1 "View node info" "" \
      2 "View configuration URL & QR code" "" \
      3 "LoRa settings" "" \
      4 "Security settings" "" \
      5 "Mesh connectivity test" "" \
      6 "Manage Meshtasticd service" "" \
      7 "Upgrade/install Meshtasticd" "" \
      8 "Uninstall Meshtasticd" "" \
      " " "" "" \
      9 "Back to main menu" "" 3>&1 1>&2 2>&3)
    [ $? -eq 1 ] && break # Exit the loop if the user selects "Cancel" or closes the dialog
    case $meshtastic_choice in
      1) # view node info)
        check_meshtasticd_running && (
          loading "Getting node info..."
          dialog --no-collapse --colors --title "Meshtastic node info" --msgbox "$(ingest_data "femto-meshtasticd-config.sh -i" 15)" 0 0
        )
        ;;
      2) # get current configuration URL & QR code)
        check_meshtasticd_running && (
          loading "Getting Meshtastic QR code and URL..."
          femto-meshtasticd-config.sh -g
          pause
        )
      ;;
      3) # LoRa settings)
        femto-meshtasticd-lora-dialogs.sh
      ;;
      4) # remote admin)
        check_meshtasticd_running && (
          choice=""   # zero the choice before loading the submenu
          while true; do
            choice=$(dialog --no-collapse --cancel-label "Back" --default-item "$choice" --title "Meshtastic Security Settings" --item-help --menu "" 16 40 5 \
              1 "View/change public key" "" \
              2 "View/change private key" "" \
              " " "" "" \
              3 "View admin keys" "" \
              4 "Set admin key" "" \
              5 "Clear admin keys" "" \
              6 "Legacy admin channel" "" \
              " " "" "" \
              7 "Return to previous menu" "" 3>&1 1>&2 2>&3)
            [ $? -eq 1 ] && break # Exit the loop if the user selects "Cancel" or closes the dialog
            case $choice in
              1) # view/change public key)
                loading "Getting current public key..."
                key=$(femto-meshtasticd-config.sh -u)
                if [ -n "$key" ]; then
                  dialog --no-collapse --title "Meshtastic public key" --yesno "Current public key:\n$key\n\nSet new key?" 9 55
                  if [ $? -eq 0 ]; then #unless cancel/no
                    key=$(dialog --no-collapse --title "Meshtastic public key" --inputbox "New Meshtastic public key (SHIFT+INS to paste):" 8 60 3>&1 1>&2 2>&3)
                    if [ $? -eq 0 ]; then #unless cancel/no
                      loading "Sending command..."
                      dialog --no-collapse --colors --title "Meshtastic public key" --msgbox "$(femto-meshtasticd-config.sh -U "$key" && echo -e "\n\Z4Command successful!\Zn\n" || echo -e "\n\Z1Command failed.\Zn\n")" 0 0
                    fi
                  fi
                else
                  dialog --no-collapse --colors --title "Meshtastic public key" --msgbox "\Z1Failed to communicate with Meshtasticd.\Zn\n\nIs the service running?\n" 0 0
                fi
              ;;
              2) # view/change private key)
                loading "Getting current private key..."
                key=$(femto-meshtasticd-config.sh -r)
                if [ -n "$key" ]; then
                  dialog --no-collapse --title "Meshtastic private key" --yesno "Current private key:\n$key\n\nSet new key?" 9 55
                  if [ $? -eq 0 ]; then #unless cancel/no
                    key=$(dialog --no-collapse --title "Meshtastic private key" --inputbox "New Meshtastic private key (SHIFT+INS to paste):" 8 60 3>&1 1>&2 2>&3)
                    if [ $? -eq 0 ]; then #unless cancel/no
                      loading "Sending command..."
                      dialog --no-collapse --colors --title "Meshtastic private key" --msgbox "$(femto-meshtasticd-config.sh -R "$key" && echo -e "\n\Z4Command successful!\Zn\n" || echo -e "\n\Z1Command failed.\Zn\n")" 0 0
                    fi
                  fi
                else
                  dialog --no-collapse --colors --title "Meshtastic private key" --msgbox "\Z1Failed to communicate with Meshtasticd.\Zn\n\nIs the service running?\n" 0 0
                fi
              ;;
              3) # view admin keys)
                loading "Getting Admin Keys..."
                dialog --no-collapse --title "Admin keys" --msgbox "Up to 3 admin keys are permitted, more will be ignored.\n\nKeys:$(femto-meshtasticd-config.sh -a | tail -n 1 | sed 's/|n/\\n/g')" 0 0
              ;;
              4) # set admin key)
                key=$(dialog --no-collapse --title "Admin Keys" --inputbox "Meshtastic admin key - up to 3, more will be ignored.\n\n(SHIFT+INS to paste):" 11 40 3>&1 1>&2 2>&3)
                if [ -n "$key" ]; then #if a key was entered
                  loading "Sending command..."
                  dialog --no-collapse --colors --title "Admin Keys" --msgbox "$(femto-meshtasticd-config.sh -A "$key" && echo -e "\n\Z4Command successful!\Zn\n" || echo -e "\n\Z1Command failed.\Zn\n")" 0 0
                fi
              ;;
              5) # clear admin keys)
                dialog --no-collapse --title "Admin Keys" --yesno "Meshtasticd can have up to 3 admin keys. If more are added, they will be ignored.\n\nClear admin key list?\n" 0 0
                if [ $? -eq 0 ]; then #unless cancel/no
                  loading "Sending command..."
                  dialog --no-collapse --colors --title "Admin Keys" --msgbox "$(femto-meshtasticd-config.sh -c && echo -e "\n\Z4Command successful!\Zn\n" || echo -e "\n\Z1Command failed.\Zn\n")" 0 0
                fi
              ;;
              6) # legacy admin)
                legacy_admin
              ;;
              7) # return to previous menu)
                break
              ;;            
            esac
          done
        )
      ;;
      5) #test mesh connectivity)
        check_meshtasticd_running && (
          dialog --no-collapse --title "Meshtastic Connectivity Test" --yesno "Will send \"test\" to channel 0 and wait for acknowledgement. Will try up to 3 times.\n\nPerform test?" 10 45
          if [ $? -eq 0 ]; then #unless cancel/no
            dialog --no-collapse --infobox "Performing mesh connectivity test.\n\nThis may take a while..." 6 45
            dialog --no-collapse --colors --title "Meshtasticd connectivity test" --msgbox "$(femto-utils.sh -R "$(femto-meshtasticd-config.sh -w)")" 0 0
          fi
        )
      ;;
      6) #manage meshtasticd service)
        choice=""   # zero the choice before loading the submenu
        while true; do
          echo "Checking Meshtasticd service state..."
          local service_state="$(femto-utils.sh -R "$(femto-utils.sh -C "meshtasticd")")"
          choice=$(dialog --no-collapse --colors --cancel-label "Back" --title "Meshtasticd Service" --default-item "$choice" --menu "Meshtasticd service is $service_state$(femto-meshtasticd-config.sh -k | grep -q 'simulated' && echo '\n\Z1Using simulated radio\Zn')" 16 52 5 \
            "View detailed service status" "x" \
            " " "" \
            "Start/restart service" "x" \
            $(if ! echo "$service_state" | grep -q 'not running'; then echo "Stop service x"; fi) \
            " " "" \
            $(if echo "$service_state" | grep -q 'disabled'; then echo "Enable service x"; fi) \
            $(if echo "$service_state" | grep -q 'enabled'; then echo "Disable service x"; fi) \
            " " "" \
            "Back to previous menu" "x" 3>&1 1>&2 2>&3)
          [ $? -eq 1 ] && break # Exit the loop if the user selects "Cancel" or closes the dialog
          case $choice in
            "View detailed service status") 
              echo "Getting Meshtasticd service status..."
              dialog --no-collapse --title "Meshtasticd service status" --msgbox "$(systemctl status meshtasticd)" 0 0
            ;;
            "Start/restart service") 
              dialog --no-collapse --title "$title" --yesno "Start/restart Meshtasticd service?" 6 45
              if [ $? -eq 0 ]; then #unless cancel/no
                femto-meshtasticd-config.sh -s
                dialog --no-collapse --colors --msgbox "Sent \`\Zusystemctl restart meshtasticd\Zn\` command to system.\n\nMeshtasticd should be running." 9 50
              fi
            ;;
            "Stop service")
              dialog --no-collapse --colors --title "$title" --yesno "Stop Meshtasticd service?\n\nThis will take the node \Zu\Z1OFFLINE\Zn.\n\nMeshtasticd will automatically restart on boot service if enabled." 11 50
              if [ $? -eq 0 ]; then #unless cancel/no
                femto-meshtasticd-config.sh -t
                dialog --no-collapse --colors --msgbox "Sent \`\Zusystemctl stop meshtasticd\Zn\` command to system.\n\nMeshtasticd should be stopped." 9 50
              fi
            ;;
            "Enable service")
              dialog --no-collapse --title "$title" --yesno "Enable Meshtasticd service?" 6 45
              if [ $? -eq 0 ]; then #unless cancel/no
                femto-meshtasticd-config.sh -M "enable"
                dialog --no-collapse --colors --msgbox "Sent \`\Zusystemctl enable meshtasticd\Zn\` and \`\Zusystemctl start meshtasticd\Zn\` commands to system.\n\nMeshtasticd should be running." 10 50
              fi
            ;;
            "Disable service")
              dialog --no-collapse --colors --title "$title" --yesno "Disable Meshtasticd service?\n\nThis will take the node \Zu\Z1OFFLINE\Zn and will not restart!" 9 50
              if [ $? -eq 0 ]; then #unless cancel/no
                femto-meshtasticd-config.sh -M "disable"
                dialog --no-collapse --colors --msgbox "Sent \`\Zusystemctl disable meshtasticd\Zn\` and \`\Zusystemctl stop meshtasticd\Zn\` commands to system.\n\nMeshtasticd should be disabled and stopped." 10 50
              fi
            ;;
            "Back to previous menu") break ;; 
          esac
        done
      ;;
      7) #Upgrade meshtasticd)
        dialog --no-collapse --title "$title" --yesno "Upgrade Meshtasticd?\nRequires internet connection." 0 0
        if [ $? -eq 0 ]; then #unless cancel/no
          femto-meshtasticd-config.sh -z
          pause
        fi
      ;;
      8) #uninstall meshtasticd)
        dialog --no-collapse --colors --title "$title" --yesno "Uninstall Meshtasticd?\n\nFoxbuntu was designed with Meshtasticd integration in mind, and may behave unexpectedly if Meshtasticd is removed.\n\nThis will take the node \Zu\Z1OFFLINE\Zn and will not restart!" 0 0
        if [ $? -eq 0 ]; then
          femto-meshtasticd-config.sh -x
          dialog --no-collapse --colors --msgbox "Meshtasticd uninstalled. To purge all remnants, run \`\Zusudo apt purge\Zn\`." 8 40
        fi
      ;;
      9)
        return
      ;;
    esac
  done
}

#Help menu
help_menu() {
  while true; do
  local title="Help / About"
    help_choice=$(dialog --no-collapse --cancel-label "Back" --default-item "$help_choice" --item-help --menu "$title" 0 0 7 \
      1 "About Femtofox" "" \
      2 "Display pinout" "" \
      3 "Femtofox licensing info - short" "" \
      4 "Femtofox licensing info - long" "" \
      5 "Meshtastic licensing info" "" \
      6 "About Luckfox" "" \
      7 "About Ubuntu" "" \
      " " "" "" \
      8 "Back to main menu" "" 3>&1 1>&2 2>&3)
    [ $? -eq 1 ] && break # Exit the loop if the user selects "Cancel" or closes the dialog    
    case $help_choice in
      1) #About Femtofox)
        dialog --no-collapse --title "About Femtofox" --default-item "$choice" --backtitle "$(femto-utils.sh -v)" --msgbox "$(femto-license.sh -a)" 18 65
      ;;
      2) #Display pinout)
        choice=""   # zero the choice before loading the submenu
        while true; do
          choice=$(dialog --no-collapse --cancel-label "Back" --default-item "$choice" --item-help --menu "Pinouts" 15 40 5 \
            1 "Femtofox Pro/CE" "" \
            2 "Femtofox Zero" "" \
            3 "Femtofox Tiny" "" \
            4 "Luckfox Pico Mini" "" \
            " " "" "" \
            5 "Back to Help Menu" "" 3>&1 1>&2 2>&3)
          [ $? -eq 1 ] && break # Exit the loop if the user selects "Cancel" or closes the dialog
          case $choice in
            1) dialog --no-collapse --title "Femtofox" --msgbox "$(femto-pinout.sh -f)" 42 68 ;;
            2) dialog --no-collapse --title "Femtofox Zero" --msgbox "$(femto-pinout.sh -z)" 34 48 ;;
            3) dialog --no-collapse --title "Femtofox Tiny" --msgbox "$(femto-pinout.sh -t)" 38 70 ;;
            4) dialog --no-collapse --title "Luckfox Pico Mini" --msgbox "$(femto-pinout.sh -l)" 23 65 ;;
            5) break ;;
          esac
        done
      ;;
      3) #Femtofox licensing info - short)
        dialog --no-collapse --title "Femtofox license" --msgbox "$(femto-license.sh -f)" 31 65
      ;;
      4) #Femtofox licensing info - long)
        clear
        femto-license.sh -F
        pause
      ;;
      5) #Meshtastic licensing info)
        dialog --no-collapse --title "Meshtastic license" --msgbox "$(femto-license.sh -m)" 0 0
      ;;
      6) #About Luckfox)
        dialog --no-collapse --title "About Luckfox" --msgbox "$(femto-license.sh -l)" 0 0
      ;;
      7) #About Ubuntu)
        dialog --no-collapse --title "About Ubuntu" --msgbox "$(femto-license.sh -u)" 0 0
      ;;
      8)
        return
      ;;
    esac
  done
}

# Parse options
help="If script is run without arguments, femto-config menu will load.\n\
Options are:\n\
-h           This message\n\
-l           Set LoRa radio model menu\n\
-L           Meshtastic legacy admin menu\n\
-w           Set Wi-Fi config menu\
-c           Check if Meshtasticd is running and warn the user if not\
"
while getopts ":hlLwc" opt; do
  case ${opt} in
    h) # Option -h (help)
      echo -e $help
      ;;
    l) # Option -l (set lora radio)
      femto-meshtasticd-lora-dialogs.sh # this function has moved
    ;;
    L) # Option -L (Meshtastic legacy admin menu)
      legacy_admin
    ;;
    w) # Option -w (Wi-Fi config)
      wifi_config
    ;;
    c) # Option -c (Check if Meshtasticd is running and warn the user if not)
      check_meshtasticd_running
      exit $?
    ;;
    \?) # Unknown option)
      echo -e "Unknown argument $1.\n$help"
    ;;
  esac
done
[ -n "$1" ] && exit # if there were arguments, exit before loading the menu

# Main menu
while true; do
  main_menu_choice=$(dialog --no-collapse --cancel-label "Exit" --backtitle "$(femto-utils.sh -v)" --default-item "$main_menu_choice" --item-help --menu "Femtofox Config" 16 40 5 \
    1 "Settings wizard" "" \
    2 "Networking" "" \
    3 "Meshtastic" "" \
    4 "Software manager" "" \
    5 "Utilities & tools" "" \
    6 "Help" "" \
    " " "" "" \
    7 "Exit" "" 3>&1 1>&2 2>&3)
  [ $? -eq 1 ] && break # Exit the loop if the user selects "Cancel" or closes the dialog
  case $main_menu_choice in
    1) femto-install-wizard.sh ;;
    2) networking_settings ;;
    3) meshtastic_settings ;;
    4) femto-software.sh ;;
    5) utilities ;;
    6) help_menu ;;
    7) break ;;
  esac
done

exit 0
