#!/bin/bash

# import global variables
source /home/pi/monitoring/common/scripts/common_var

# import global funtions
source /home/pi/monitoring/common/scripts/common_functions

# local variables
MYSQL_SECRET=""
LOG_SOURCE=""
SOURCE_HOSTNAME=""

# functions
function print_usage() {
cat <<EOF
Usage:

  server_import [OPTION]...

Options:

    -w, --wlan HOSTNAME LOG_NUMBER [IP_ADDRESS]
      Import ${LOG_NODE_AIRODUMP} log with specified number from device with specified
      hostname and optionally IP address.
      Argument hostname will be prefixed with 'rpi_mon_', therefore ONLY last
      bit of hostname needs to be specified (eg. node_1).

    -w5, --wlan5 HOSTNAME LOG_NUMBER [IP_ADDRESS]
      Import ${LOG_NODE_AIRODUMP_5GHZ} log with specified number from device with specified
      hostname and optionally IP address.
      Argument hostname will be prefixed with 'rpi_mon_', therefore ONLY last
      bit of hostname needs to be specified (eg. node_1).

    -b, --bt HOSTNAME [IP_ADDRESS]
      Import Bluelog log from device with specified hostname and optionally
      IP address.
      Argument hostname will be prefixed with 'rpi_mon_', therefore ONLY last
      bit of hostname needs to be specified (eg. node_1).

    --help
      Print help page.

Examples:

  server_import -w node_1 01
  server_import -w5 node_1 01
  server_import -b node_1 192.168.0.31 -w node_2 01 192.168.0.31

EOF
}

function print_help() {
cat <<EOF

SERVER: IMPORT DATA FROM MONITORING NODE LOGS INTO DATABASE

This command is used to import data from monitoring node logs into MySQL
database. It can import logs from both local and remote monitoring devices.
Suitable database must exist prior to calling this script.

For more information try using 'server_db --help'.

Server log directory:          ${DIR_SERVER_LOGS}
Monitoring node log directory: $DIR_NODE_LOGS

Server imports log name:       ${LOG_SERVER_IMPORT}
2.4GHz wlan log name:          $LOG_NODE_AIRODUMP
5GHz wlan log name:            $LOG_NODE_AIRODUMP_5GHZ

Location cannot be altered because scripts on this or remote device
might be depending on it!

EOF
print_usage
}

function import_wlan() {
  # first  argument - wlan standard (a/bg)
  # second argument - hostname ending (rpi_mon_###) (database name)
  # third  argument - log number (aircrack-ng-##.csv)
  # fourth argument - IP address of source (optional)
  # return 0 - function finished
  # return 1 - copy command failed
  # return 2 - mysqlimport failed

  echo "==============================="
  echo "Starting database import (wlan)"
  echo "==============================="

  # local variables
  ROW_APS=2
  ROW_CLIENTS=0
  ROW_TOTAL=0
  ROW_START=0
  ROW_END=0
  SED_STRING=""
  CP_LOG_FROM=""
  CP_LOG_TO=""
  LOG_FILE=""

  # determine variables from function arguments
  SOURCE_HOSTNAME="rpi_mon_${2}"
  case $1 in
    "a")
      LOG_FILE_NAME=${LOG_NODE_AIRODUMP_5GHZ}
      ;;
    "bg")
      LOG_FILE_NAME=${LOG_NODE_AIRODUMP}
      ;;
  esac

  # check if mysql password passed as -a argument
  if [[ "${MYSQL_SECRET}" == "" ]];
  then
    # mysql password prompt - passwd returned in MYSQL_SECRET variable
    mysql_passwd_check ${SERVER_DB_MON_USER}
  fi

  # generate "random" number from current time to avoid collision of files
  RAND=$(date +%s%N)
  
  ##
  # copy to local mysql dir
  LOG_FILE="${DIR_MYSQL}/${LOG_FILE_NAME}-${3}.${RAND}"

  if [ "${4}" == "" ];
  then
    # local copy
    CP_LOG_FROM="${DIR_NODE_LOGS}/${LOG_FILE_NAME}-${3}.csv"
    CP_LOG_TO="${LOG_FILE}.csv"
    LOG_SOURCE="${CP_LOG_FROM}"
    echo "Copying local log file from: '${CP_LOG_FROM}' to: '${CP_LOG_TO}'..."
    cp "${CP_LOG_FROM}" "${CP_LOG_TO}"
  else
    # remote copy
    CP_LOG_FROM="pi@${4}:${DIR_NODE_LOGS}/${LOG_FILE_NAME}-${3}.csv"
    CP_LOG_TO="/tmp/${LOG_FILE_NAME}-${3}.${RAND}.csv"
    LOG_SOURCE="${CP_LOG_FROM}"
    echo "Copying remote log file from: '${CP_LOG_FROM}' to temporary location: '${CP_LOG_TO}'..."
    sudo -u pi scp "${CP_LOG_FROM}" "${CP_LOG_TO}"
    CP_LOG_FROM="${CP_LOG_TO}"
    CP_LOG_TO="${LOG_FILE}.csv"
    echo "Moving temporary log file from: '${CP_LOG_FROM}' to: '${CP_LOG_TO}'..."
    mv "${CP_LOG_FROM}" "${CP_LOG_TO}"
  fi

  # check for failed copy command
  if [[ ! -f "${CP_LOG_TO}" ]];
  then
    echo "ERROR: copy command failed!"
    return 1
  fi
     
  echo "Parsing local copy of log file..."
  # remove carriage returns
  sed -i 's/\r$//g' ${LOG_FILE}.csv
  # remove unwanted delimiters
  sed -i '/|~|/d' ${LOG_FILE}.csv
  
  # determine data ranges
  ROW_CLIENTS=$(sed -n '/Station MAC/=' ${LOG_FILE}.csv)
  ROW_TOTAL=$(grep "" -c ${LOG_FILE}.csv)

  ##
  # extract AccessPoints csv
  ROW_START=$ROW_APS
  ROW_END=$((ROW_CLIENTS-2))
  SED_STRING="${ROW_START},${ROW_END}p;$((ROW_END+1))q"
  echo "Extracting AccessPoints (row ${ROW_START} to ${ROW_END}; total $((ROW_END-ROW_START)))..."
  sed -n $SED_STRING ${LOG_FILE}.csv > ${LOG_FILE}-AccessPoints.csv
      
  # parse AccessPoints into custom csv
  # insert wlan standard to last column
  echo "Parsing extracted AccessPoints log file into csv..."
  awk -F', ' 'BEGIN{OFS="|~|"} {print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,"'${1}'"}' \
  ${LOG_FILE}-AccessPoints.csv > ${DIR_MYSQL}/AccessPoints.${RAND}.csv
  
  ##    
  # extract Clients csv
  ROW_START=$ROW_CLIENTS
  ROW_END=$((ROW_TOTAL-1))
  SED_STRING="${ROW_START},${ROW_END}p;$((ROW_END+1))q"
  echo "Extracting Clients (row ${ROW_START} to ${ROW_END}; total $((ROW_END-ROW_START)))..."
  sed -n $SED_STRING ${LOG_FILE}.csv > ${LOG_FILE}-Clients.csv
      
  # parse Clients into custom csv
  # insert wlan standard to last column
  echo "Parsing extracted Clients log file into csv..."
  awk -F', ' 'BEGIN{OFS="|~|"} {print $1,$2,$3,$4,$5,$6,"'${1}'"}' \
  ${LOG_FILE}-Clients.csv > ${DIR_MYSQL}/Clients.${RAND}.csv
  
  ##    
  # database querry
  echo "Importing extracted data into database 'rpi_mon_${2}'..."
  mysqlimport -u ${SERVER_DB_MON_USER} -p${MYSQL_SECRET} \
  --verbose \
  --low-priority \
  --replace \
  --fields-terminated-by='|~|' \
  --lines-terminated-by='\n' \
  --ignore-lines=1 \
  --columns=BSSID,first_time_seen,last_time_seen,channel,speed,privacy,cipher,authentication,power,beacons,IV,LAN_IP,ID_length,ESSID,passphrase,standard \
  ${SOURCE_HOSTNAME} \
  ${DIR_MYSQL}/AccessPoints.${RAND}.csv
      
  # check exit code of mysqlimport (AccessPoints)
  if [ $? = "0" ];
  then
    echo "MySQL: import of AccessPoints finished successfully!"
  else
    echo "ERROR MySQL: import of AccessPoints failed!"
    return 2
  fi

  mysqlimport -u ${SERVER_DB_MON_USER} -p${MYSQL_SECRET} \
  --verbose \
  --low-priority \
  --replace \
  --fields-terminated-by='|~|' \
  --lines-terminated-by='\n' \
  --ignore-lines=1 \
  --columns=station_MAC,first_time_seen,last_time_seen,power,packets,probed_ESSIDs,standard \
  ${SOURCE_HOSTNAME} \
  ${DIR_MYSQL}/Clients.${RAND}.csv
      
  # check exit code of mysqlimport (Clients)
  if [ $? = "0" ];
  then
    echo "MySQL: import of Clients finished successfully!"
  else
    echo "ERROR MySQL: import of Clients failed!"
    return 2
  fi
      
  return 0
}

function import_bt() {
  # first  argument - hostname ending (rpi_mon_###)
  # second argument - IP address of remote monitoring device (optional)

  echo "============================="
  echo "Starting database import (bt)"
  echo "============================="
  
  #local variables
  LOG_FILE=""
  CP_LOG_TO=""
  CP_LOG_FROM=""
  SOURCE_HOSTNAME="rpi_mon_${1}"

  # check if mysql password passed as -a argument
  if [[ "${MYSQL_SECRET}" == "" ]];
  then
    # mysql password prompt - passwd returned in MYSQL_SECRET variable
    mysql_passwd_check ${SERVER_DB_MON_USER}
  fi

  # generate "random" number from current time to avoid collision of files
  RAND=$(date +%s%N)

  # copy to local mysql dir
  LOG_FILE="${DIR_MYSQL}/${LOG_NODE_BLUELOG}.${RAND}"
      
  if [ "$2" == "" ];
  then
    # local copy
    CP_LOG_FROM="${DIR_NODE_LOGS}/${LOG_NODE_BLUELOG}.log"
    CP_LOG_TO="${LOG_FILE}.log"
    LOG_SOURCE="${CP_LOG_FROM}"
    echo "Copying local log file from: '${CP_LOG_FROM}' to: '${CP_LOG_TO}'..."
    cp "${CP_LOG_FROM}" "${CP_LOG_TO}"
  else
    # remote copy
    CP_LOG_FROM="pi@${2}:${DIR_NODE_LOGS}/${LOG_NODE_BLUELOG}.log"
    CP_LOG_TO="/tmp/${LOG_NODE_BLUELOG}.${RAND}.log"
    LOG_SOURCE="${CP_LOG_FROM}"
    echo "Copying remote log file from: '${CP_LOG_FROM}' to temporary location: '${CP_LOG_TO}'..."
    sudo -u pi scp "${CP_LOG_FROM}" "${CP_LOG_TO}"
    CP_LOG_FROM="${CP_LOG_TO}"
    CP_LOG_TO="${LOG_FILE}.log"
    echo "Moving temporary log file from: '${CP_LOG_FROM}' to: '${CP_LOG_TO}'..."
    mv "${CP_LOG_FROM}" "${CP_LOG_TO}"
  fi
      
  # check for failed copy command
  if [[ ! -f "${CP_LOG_TO}" ]];
  then
    echo "ERROR: copy command failed!"
    return 1
  fi

  echo "Parsing local copy of log file into csv..."
  # remove Scan start/stop lines
  sed -i '/Scan /d' ${LOG_FILE}.log
  # remove unwanted delimiters
  sed -i '/|~|/d' ${LOG_FILE}.log
  # change csv delimiters and extract first 6 columns
  awk -F',' 'BEGIN{OFS="|~|"} {print $1,$2,$3,$4,$5,$6}' \
  ${LOG_FILE}.log > ${DIR_MYSQL}/Bluetooth.${RAND}.csv

  # database querry
  echo "Importing formated data into database 'rpi_mon_${1}'..."
  mysqlimport -u ${SERVER_DB_MON_USER} -p${MYSQL_SECRET} \
  --verbose \
  --low-priority \
  --replace \
  --fields-terminated-by='|~|' \
  --lines-terminated-by='\n' \
  --columns=last_time_seen,BD_ADDR,class,class_detail,OUI,device_name \
  ${SOURCE_HOSTNAME} \
  ${DIR_MYSQL}/Bluetooth.${RAND}.csv
      
  # check exit code of mysqlimport (Bluetooth)
  if [ $? = "0" ];
  then
    echo "MySQL: import of Bluetooth finished successfully!"
  else
    echo "ERROR MySQL: import of Bluetooth failed!"
    return 2
  fi

  return 0
}

# options parsing

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

while [ $# -gt 0 ]
do
  case $1 in
    --help)
      print_help
      exit 0
      ;;

    -a|--auto)
      # arguments
      # $2 - mysql password

      # check if argument $2 empty
      if [[ -z "$2" ]] || [[ "$2" = -* ]];
      then
        echo "ERROR: invalid argument '${2}' for option ${1}!"
        print_usage
	exit 1
        break
      fi

      MYSQL_SECRET="${2}"

      shift 2
      ;;
    
    -w|--wlan)
      # arguments
      # $2 - hostname ending (rpi_mon_###)
      # $3 - log number (aircrack-ng-##.csv)
      # $4 - [IP address of remote monitoring device] (optional)

      # check if argument $2 empty
      if [[ -z "$2" ]] || [[ "$2" = -* ]];
      then
        echo "ERROR: invalid argument '${2}' for option ${1}!"
        print_usage
	exit 1
        break
      fi
      
      # check if argument $3 empty
      if [[ -z "$3" ]] || [[ "$3" = -* ]];
      then
        echo "ERROR: invalid argument '${3}' for option ${1}!"
        print_usage
	exit 1
        break
      fi
      
      # check optional argument $4
      if [[ -z "$4" ]] || [[ "$4" = -* ]];
      then
        import_wlan "bg" $2 $3
      else
        import_wlan "bg" $2 $3 $4
      fi

      RET_VAL=$?
      
      # import_wlan return:
      # 0 - successfully finished
      # 1 - copy command failed
      # 2 - mysqlimport failed
      echo "[$(timestamp)] writing database import log entry to '${DIR_SERVER_LOGS}/${LOG_SERVER_IMPORT}.log'..."
      case $RET_VAL in
        0)
          log_server_import "successful" "wlan" "${SOURCE_HOSTNAME}" "${LOG_SOURCE}"
          # remove runtime files
          echo "Removing runtime files..."
          rm ${LOG_FILE}*
          rm ${DIR_MYSQL}/AccessPoints.${RAND}.csv
          rm ${DIR_MYSQL}/Clients.${RAND}.csv
          ;;
        1)
          log_server_import "failed copy" "wlan" "${SOURCE_HOSTNAME}" "${LOG_SOURCE}"
          ;;
        2)
          log_server_import "failed import" "wlan" "${SOURCE_HOSTNAME}" "${LOG_SOURCE}"
          # remove runtime files
          echo "Removing runtime files..."
          rm ${LOG_FILE}*
          rm ${DIR_MYSQL}/AccessPoints.${RAND}.csv
          rm ${DIR_MYSQL}/Clients.${RAND}.csv
          ;;
        esac

      if [[ -z "$4" ]] || [[ "$4" = -* ]];
      then
        shift 3
      else
        shift 4
      fi
      ;;
    
    -w5|--wlan5)
      # arguments
      # $2 - hostname ending (rpi_mon_###)
      # $3 - log number (aircrack-ng-##.csv)
      # $4 - [IP address of remote monitoring device] (optional)

      # check if argument $2 empty
      if [[ -z "$2" ]] || [[ "$2" = -* ]];
      then
        echo "ERROR: invalid argument '${2}' for option ${1}!"
        print_usage
	exit 1
        break
      fi
      
      # check if argument $3 empty
      if [[ -z "$3" ]] || [[ "$3" = -* ]];
      then
        echo "ERROR: invalid argument '${3}' for option ${1}!"
        print_usage
	exit 1
        break
      fi
      
      # check optional argument $4
      if [[ -z "$4" ]] || [[ "$4" = -* ]];
      then
        import_wlan "a" $2 $3
      else
        import_wlan "a" $2 $3 $4
      fi

      RET_VAL=$?
      
      # import_wlan return:
      # 0 - successfully finished
      # 1 - copy command failed
      # 2 - mysqlimport failed
      echo "[$(timestamp)] writing database import log entry to '${DIR_SERVER_LOGS}/${LOG_SERVER_IMPORT}.log'..."
      case $RET_VAL in
        0)
          log_server_import "successful" "wlan5" "${SOURCE_HOSTNAME}" "${LOG_SOURCE}"
          # remove runtime files
          echo "Removing runtime files..."
          rm ${LOG_FILE}*
          rm ${DIR_MYSQL}/AccessPoints.${RAND}.csv
          rm ${DIR_MYSQL}/Clients.${RAND}.csv
          ;;
        1)
          log_server_import "failed copy" "wlan5" "${SOURCE_HOSTNAME}" "${LOG_SOURCE}"
          ;;
        2)
          log_server_import "failed import" "wlan5" "${SOURCE_HOSTNAME}" "${LOG_SOURCE}"
          # remove runtime files
          echo "Removing runtime files..."
          rm ${LOG_FILE}*
          rm ${DIR_MYSQL}/AccessPoints.${RAND}.csv
          rm ${DIR_MYSQL}/Clients.${RAND}.csv
          ;;
        esac

      if [[ -z "$4" ]] || [[ "$4" = -* ]];
      then
        shift 3
      else
        shift 4
      fi
      ;;
    
    -b|--bt)
      # arguments
      # $2 - hostname ending (rpi_mon_###)
      # $3 - [IP address of remote monitoring device] (optional)

      # check if argument $2 empty
      if [[ -z "$2" ]] || [[ "$2" = -* ]];
      then
        echo "ERROR: invalid argument '${2}' for option ${1}!"
        print_usage
	exit 1
        break
      fi
      
      if [[ -z "$3" ]] || [[ "$3" = -* ]];
      then
        import_bt $2
      else
        import_bt $2 $3
      fi
      
      RET_VAL=$?
      
      # import_bt return:
      # 0 - successfully finished
      # 1 - copy command failed
      # 2 - mysqlimport failed
      echo "[$(timestamp)] writing database import log entry to '${DIR_SERVER_LOGS}/${LOG_SERVER_IMPORT}.log'..."
      case $RET_VAL in
        0)
          log_server_import "successful" "bt" "${SOURCE_HOSTNAME}" "${LOG_SOURCE}"
          # remove runtime files
          echo "Removing runtime files..."
          rm ${LOG_FILE}*
          rm ${DIR_MYSQL}/Bluetooth.${RAND}.csv
          ;;
        1)
          log_server_import "failed copy" "bt" "${SOURCE_HOSTNAME}" "${LOG_SOURCE}"
          ;;
        2)
          log_server_import "failed import" "bt" "${SOURCE_HOSTNAME}" "${LOG_SOURCE}"
          # remove runtime files
          echo "Removing runtime files..."
          rm ${LOG_FILE}*
          rm ${DIR_MYSQL}/Bluetooth.${RAND}.csv
          ;;
        esac

      if [[ -z "$3" ]] || [[ "$3" = -* ]];
      then
        shift 2
      else
        shift 3
      fi
      ;;
    
    *)
      echo "ERROR: option $1 unknown!"
      print_usage
      exit 1
      break
      ;;
  esac
  
done

