#!/bin/bash

#
# wconsole_switcher - script to switch wconsole on/off
#                     (usually called from the WLANPi menu system)    
#
# Written by Nigel Bowden <wifinigel@gmail.com>.
#

set -e

NAME="wconsole_switcher"
DESC="Script to switch wconsole on/off"
STATUS_FILE="/etc/wlanpi-state"
WCONSOLE_CONF_FILE="/etc/wlanpi-wconsole/conf/hostapd.conf"
HOTSPOT_CONF_FILE="/etc/wlanpi-hotspot/conf/hostapd.conf"

if [[ $EUID -ne 0 ]]; then
   echo "Error: This script must be run as root"
   exit 1
fi

###############################################################################
#
# Activate wconsole:
#
# 1. Backup various existing files to allow restoration when Wi-Fi console
#    deactivated
# 2. Remove a number of existing files that need to be replaced
# 3. Create links from deleted file locations to Wi-Fi console config files
# 4. Update ufw to allow tcp ports through that may be used for access
# 5. Create status file to indicate Wi-Fi console is active
# 6. Reboot the wlanpi to ensure clean activation
#
###############################################################################

wconsole_on () {

  echo "Starting switch from Classic mode to Wi-Fi Console mode"

  # check what state the WLAN Pi is in
  PI_STATUS=`cat $STATUS_FILE | grep 'classic'` || true
  if  [ -z "$PI_STATUS" ]; then
     echo "Failed: WLAN Pi is not in Classic mode"
     exit 1
  fi

  # check we have the ser2net service installed
  SER2NET_STATUS=`systemctl status ser2net| grep ser2net.service`
  if  [ -z "$SER2NET_STATUS" ]; then
     echo "Failed: ser2net service not found"
     exit 1
  fi

  # check we have the hostapd service installed
  HOSTAPD_STATUS=`systemctl status hostapd --no-pager | grep hostapd.service`
  if  [ -z "$HOSTAPD_STATUS" ]; then
     echo "Failed: hostapd service not found"
     exit 1
  fi

  # check if the WLAN NIC supports AP mode before switching
  # iw list | awk '/Supported interface modes/, /Band/' | grep '\* AP'
   AP_SUPPORT=`iw list | awk '/Supported interface modes/, /Band/' | grep '\* AP'` || true
   if  [ -z "$AP_SUPPORT" ]; then
     echo "Failed: AP Mode not supported by adapter"
     exit 1
  fi

   # check if we are using the factory shipped SSID, rename if we are
  echo "Checking for factory default SSID name"
  if grep -q -E "^?ssid=WLAN Pi Default SSID" $HOTSPOT_CONF_FILE && grep -q -E "^?ssid=WLAN Pi Default SSID" $WCONSOLE_CONF_FILE; then
    echo "Creating a unique SSID as using default SSID"

    # Get the last 3 chars of eth0 MAC address
    LAST_3_CHARS_MAC=$(sed s/://g /sys/class/net/eth0/address | grep -o '...$')

    # Check if we got 3 chars
    if [ ${#LAST_3_CHARS_MAC} -ne 3 ]; then
      echo "Failed: Couldn't get eth0 MAC address during unique SSID creation"
      exit 1
    fi

    # Configure the unique SSID
    sed -i "s/^#\?ssid=.*/ssid=WLAN Pi $LAST_3_CHARS_MAC/" $WCONSOLE_CONF_FILE
    sed -i "s/^#\?ssid=.*/ssid=WLAN Pi $LAST_3_CHARS_MAC/" $HOTSPOT_CONF_FILE

  else
    echo "SSID is already customised"
  fi

  if grep -q -E "^?wpa_passphrase=WL@NP123" $HOTSPOT_CONF_FILE && grep -q -E "^?wpa_passphrase=WL@NP123" $WCONSOLE_CONF_FILE; then
    echo "Generating a new random WPA2 passphrase"
    PASSPHRASE=$(tr -dc 'A-Ha-h2-9J-Kj-k2-9M-Nm-n2-9P-Zp-z2-9' </dev/urandom | head -c 12  ; echo)
    # substitute in new random pwd
    sed -i "s/^#\?wpa_passphrase=.*/wpa_passphrase=$PASSPHRASE/" $WCONSOLE_CONF_FILE
    sed -i "s/^#\?wpa_passphrase=.*/wpa_passphrase=$PASSPHRASE/" $HOTSPOT_CONF_FILE

  else
    echo "WPA2 passphrase is already customised"
  fi

  echo "Enabling Wi-Fi console ..."
  # Backup files
  echo "Backing up existing config files ..."
  if [ -e /etc/default/isc-dhcp-server ]; then
    cp /etc/default/isc-dhcp-server /etc/default/isc-dhcp-server.wcon
  fi
  if [ -e /etc/dhcp/dhcpd.conf ]; then
  cp /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.wcon
  fi
  if [ -e /etc/network/interfaces ]; then
    cp /etc/network/interfaces /etc/network/interfaces.wcon
  fi
  if [ -e /etc/sysctl.conf ]; then
    cp /etc/sysctl.conf /etc/sysctl.conf.wcon
  fi
  if [ -e /etc/default/ufw ]; then
    cp /etc/default/ufw /etc/default/ufw.wcon
  fi
  if [ -e /etc/ufw/before.rules ]; then
  cp /etc/ufw/before.rules /etc/ufw/before.rules.wcon
  fi
  # These files may or may not exist
  if [ -e /etc/ser2net.conf ]; then
    cp /etc/ser2net.conf /etc/ser2net.conf.wcon
  fi
  if [ -e /etc/hostapd/hostapd.conf ]; then
    cp /etc/hostapd/hostapd.conf /etc/hostapd/hostapd.conf.wcon
  fi

  # Remove existing files
  rm -f /etc/default/isc-dhcp-server
  rm -f /etc/dhcp/dhcpd.conf
  rm -f /etc/network/interfaces
  rm -f /etc/sysctl.conf
  rm -f /etc/default/ufw
  rm -f /etc/ufw/before.rules

  # These files may or may not exist
  if [ -e /etc/ser2net.conf ]; then
    rm /etc/ser2net.conf
  fi
  if [ -e /etc/hostapd/hostapd.conf ]; then
    rm /etc/hostapd/hostapd.conf
  fi

  # Create directory if it doesn't exist
  if [ ! -d "/etc/hostapd" ]; then
      echo "Directory /etc/hostapd does not exist. Creating it..."
      mkdir -p "/etc/hostapd"
  fi

  # Link to files in wconsole
  ln -s /etc/wlanpi-wconsole/default/isc-dhcp-server /etc/default/isc-dhcp-server
  ln -s /etc/wlanpi-wconsole/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf
  ln -s /etc/wlanpi-wconsole/network/interfaces /etc/network/interfaces
  ln -s /etc/wlanpi-wconsole/conf/ser2net.conf /etc/ser2net.conf
  ln -s /etc/wlanpi-wconsole/conf/hostapd.conf /etc/hostapd/hostapd.conf
  ln -s /etc/wlanpi-wconsole/sysctl/sysctl.conf /etc/sysctl.conf
  ln -s /etc/wlanpi-wconsole/default/ufw /etc/default/ufw
  ln -s /etc/wlanpi-wconsole/ufw/before.rules /etc/ufw/before.rules

  # Open up console ports on FW
  ufw allow 2400:2408/tcp
  ufw allow 4800:4808/tcp
  ufw allow 9600:9608/tcp
  ufw allow 19200:19208/tcp
  ufw allow 38400:38408/tcp
  ufw allow 11520:11528/tcp
  ufw allow 2000:2008/tcp

  # Enable services to start after reboot
  systemctl enable hostapd ser2net isc-dhcp-server

  # Signal that wconsole active
  echo "wconsole" > $STATUS_FILE
  echo "WLAN Pi will now reboot to launch Wi-Fi Console mode ..."
  sleep 1
  reboot
}

###############################################################################
#
# Deactivate wconsole:
#
# 1. Remove links created during activation
# 2. Restore config files backed up during activation
# 3. Remove firewall rules added during activation
# 4. Remove status file to indicate Wi-Fi console no longer active
# 5. Reboot wlanpi to provide clean restoration of services
#
###############################################################################

wconsole_off () {

  # check what state the WLAN Pi is in
  PI_STATUS=`cat $STATUS_FILE | grep 'wconsole'` || true
  if  [ -z "$PI_STATUS" ]; then
     echo "Failed: WLAN Pi is not in wconsole mode"
     exit 1
  fi

  echo "Disabling Wi-Fi console ..."
  # Remove sym links to wconsole
  unlink /etc/default/isc-dhcp-server
  unlink /etc/dhcp/dhcpd.conf
  unlink /etc/network/interfaces
  unlink /etc/ser2net.conf
  unlink /etc/hostapd/hostapd.conf
  unlink /etc/sysctl.conf
  unlink /etc/default/ufw
  unlink /etc/ufw/before.rules

  # Restore old files
  cp /etc/default/isc-dhcp-server.wcon /etc/default/isc-dhcp-server
  cp /etc/dhcp/dhcpd.conf.wcon /etc/dhcp/dhcpd.conf
  cp /etc/network/interfaces.wcon /etc/network/interfaces
  cp /etc/sysctl.conf.wcon /etc/sysctl.conf
  cp /etc/default/ufw.wcon /etc/default/ufw
  cp /etc/ufw/before.rules.wcon /etc/ufw/before.rules
  # These files may or may not exist
  if [ -e /etc/ser2net.conf.wcon ]; then
    cp /etc/ser2net.conf.wcon /etc/ser2net.conf
  fi
  if [ -e /etc/hostapd/hostapd.conf.wcon ]; then
    cp /etc/hostapd/hostapd.conf.wcon /etc/hostapd/hostapd.conf
  fi
  # Close ports on FW
  ufw delete allow 2400:2408/tcp
  ufw delete allow 4800:4808/tcp
  ufw delete allow 9600:9608/tcp
  ufw delete allow 19200:19208/tcp
  ufw delete allow 38400:38408/tcp
  ufw delete allow 2000:2008/tcp
  ufw delete allow 11520:11528/tcp

  # Disable services to start after reboot
  systemctl disable hostapd ser2net isc-dhcp-server

  echo "WLAN Pi will now reboot ..."
  echo "classic" > $STATUS_FILE
  sleep 1
  reboot
}

status () {
  PI_STATUS=`cat $STATUS_FILE | grep 'wconsole'` || true
  if  [ -z "$PI_STATUS" ]; then
    echo "wconsole is currently disabled"
    exit 0
  else
    echo "wconsole is currently enabled"
    exit 0
  fi

}


version () {
  VERSION=$(apt list --installed wlanpi-wconsole 2>/dev/null | grep wlanpi-wconsole | awk '{print $2}')
  echo "Version: $VERSION" >&2
  exit 0
}

case "$1" in
  on)
        wconsole_on
        ;;
  off)
        wconsole_off
        ;;
  status)
        status
        ;;
  version)
        version;;
  *)
        N=/etc/wlanpi-wconsole/$NAME
        echo "Usage: $N {on|off|status|version}" >&2
        exit 1
        ;;
esac

exit 0
