#!/bin/bash

BASH_PATH=$(which bash)

#########
# GLOBALS
#########
REPO_TOP=$(dirname $(readlink -f "${BASH_SOURCE[0]}"))
SCRIPT_NAME=$(basename $0)
SERVER_MODE=0 # 1=true, 0=false
CLIENT_MODE=0 # 1=true, 0=false
LOG_LEVEL=1
BUILD_PATH="build"
RUN_PATH="run"
RESET_ALL=0
RUN_ALL=1
GRADLEW_PATH=${REPO_TOP}/gradlew
declare SERVER_PID
declare CLIENT_PID

# $1 is text level
# LEVELS:
# 1: Info
# 2: Debug
# 3: Warning
function TermWrite() {
	textLevel=$1
	text="${2}"
	prefix="[\033[34m"${SCRIPT_NAME}"\033[0m]: "

	if [[ "${textLevel}" == "2" ]]; then
		prefix="[\033[33m"${SCRIPT_NAME}"\033[0m]:"
	fi

	if [[ "${textLevel}" == "3" ]]; then
		prefix="[\033[31m"${SCRIPT_NAME}"\033[0m]:"
	fi

  if [[ ${LOG_LEVEL} -ge ${textLevel} ]]; then
	  printf "${prefix} ${text}\n"
  fi
}

function help() {
  echo -e "Help for running $0:"
  echo -e " -s:          Build and run the program in server mode"
  echo -e " -c:          Build and run the program in client mode"
  echo -e " -l  [1-3]:   Turn up the logging level to see more messages (default: 1)"
  echo -e " -g  <path>:  The path to the gradlew executable (default: $(pwd)/gradlew)"
  echo -e " -r:          Reset everything. This will nuke the previous install area and re-build EVERYTHING from scratch"
  echo -e " -b  <path>:  Specify the build area (default is cur dir $(pwd)/build)"
  echo -e " -b2 <path>:  Specify the run area (default is cur dir $(pwd)/run)"
  echo -e " -a:          Run everything at once (default option if nothing specified)"
  echo -e " -h:          Bring up this help message"
}

function ExitAll() {
  TermWrite 1 "Cleaning up..."
  if [ ! -z $SERVER_PID ]; then
    TermWrite 1 "Killing PID $SERVER_PID"
    kill -9 $SERVER_PID
  fi

  if [ ! -z $CLIENT_PID ]; then
    TermWrite 1 "Killing PID $CLIENT_PID"
    kill -9 $CLIENT_PID
  fi

  # Close with exit code 1 because a clean close isn't guarenteed with this
  exit 1
}

# Capture CTRL+C event into ExitAll function
trap ExitAll INT

while getopts ":schl:g:r:b:b2:" opt; do
  case ${opt} in
    s)
      TermWrite 2 "SERVER MODE ENABLED"
      SERVER_MODE=1
      RUN_ALL=0
      ;;
    c)
      TermWrite 2 "CLIENT MODE ENABLED"
      CLIENT_MODE=1
      RUN_ALL=0
      ;;
    h)
      help
      exit 0
      ;;
    l)
      if [[ $OPTARG =~ [1-3] ]]; then
        LOG_LEVEL=$OPTARG
        TermWrite 2 "LOG LEVEL SET TO $LOG_LEVEL"
      fi
      ;;
    g)
      if [[ -f "${OPTARG}" ]]; then
        TermWrite 2 "Set gradlew path to $OPTARG"
        GRADLEW_PATH="$OPTARG"
      else
        TermWrite 3 "The path you gave to the gradlew executable (${OPTARG}) does not appear to exist. Please check the path!"
      fi
      ;;
    r)
      RESET_ALL=1
      ;;
    b)
      if [[ -f "${OPTARG}" ]]; then
        TermWrite 2 "Setting build directory to: ${OPTARG}"
        BUILD_PATH="${OPTARG}"
      else
        TermWrite 3 "The specified path (${OPTARG}) does not appear to exist. Please check the path!"
        exit 1
      fi
      ;;
    b1)
      if [[ "${OPTARG}" ]]; then
        TermWrite 2 "Setting run directory to: ${OPTARG}"
        RUN_PATH="${OPTARG}"
      else
        TermWrite 3 "The specified path (${OPTARG}) does not appear to exist. Please check the path!"
        exit 1
      fi
      ;;
    ?)
      help
      exit 0
      ;;
  esac
done

TermWrite 2 "CURRENT DIRECTORY: $(pwd)"
TermWrite 2 "SERVER MODE? ${SERVER_MODE}"
TermWrite 2 "CLIENT MODE? ${CLIENT_MODE}"

# If the user specified they wish to wipe everything before we begin; then let us do so.
if [[ $RESET_ALL -eq 1 ]]; then
  TermWrite 1 "Removing $BUILD_PATH"
  rm -rf $BUILD_PATH
  TermWrite 1 "Removing $RUN_PATH"
  rm -rf $RUN_PATH

  TermWrite 1 "Running build..."
  $BASH_PATH $GRADLEW_PATH build
  TermWrite 1 "Running datagen..."
  $BASH_PATH $GRADLEW_PATH runDatagen
  TermWrite 1 "All completed!"
fi

if [[ $RUN_ALL -eq 0 ]]; then
  if [[ $SERVER_MODE -eq 1 ]]; then
    TermWrite 1 "Running ./gradlew build"
    $BASH_PATH $GRADLEW_PATH build
    TermWrite 1 "Running ./gradlew runServer"
    $BASH_PATH $GRADLEW_PATH runServer &
    SERVER_PID=$!
  fi

  if [[ $CLIENT_MODE -eq 1 ]]; then
    TermWrite 1 "Running ./gradlew build"
    $BASH_PATH $GRADLEW_PATH build
    TermWrite 1 "Running ./gradlew runClient"
    $BASH_PATH $GRADLEW_PATH runClient
    CLIENT_PID=$!
  fi
else
  # Run everything
  TermWrite 1 "Running both client and server processes..."
  $BASH_PATH $GRADLEW_PATH clean
  $BASH_PATH $GRADLEW_PATH build
  $BASH_PATH $GRADLEW_PATH runClient &
  CLIENT_PID=$!
  # We do not run the server in the background so the player may run commands in the server terminal
  $BASH_PATH $GRADLEW_PATH runServer
  SERVER_PID=$!

  TermWrite 1 "Server and client processes started"
fi

TermWrite 1 "Finished running gradlew command with exit code $?"

# We wait and hang here until BOTH background processes finish (or until CTRL+C event)
wait

# Clean up and leave
ExitAll
