#!/bin/bash

#
# Some commands have arguments with embedded spaces.
# Need to preserve the # grouping, so enclose every argument in quotes.
#

SCRIPT=$(readlink -f "$0")
# Absolute path this script is in, thus /home/user/bin
APP_PATH=$(dirname "$SCRIPT")
# Get the directory above bin for DCSTOOL_HOME
DH=$(realpath "${APP_PATH}/..")

# Make sure DCSTOOL_HOME is set
if [ -z "$DCSTOOL_HOME" ]
then
  DCSTOOL_HOME=$DH
  export DCSTOOL_HOME
elif [ "$DH" != "$(realpath ${DCSTOOL_HOME})" ]
then
  echo "Environment has set a different DCSTOOL_HOME than the location of the application start script."
  echo "Environment $DCSTOOL_HOME"
  echo "Location    $DH"
  echo "This may cause incorrect operation."
fi


# Make sure DECODES_INSTALL_DIR is set
if [ -z "$DECODES_INSTALL_DIR" ]
then
  DECODES_INSTALL_DIR=$DH
  export DECODES_INSTALL_DIR
fi

# Make sure DCSTOOL_USERDIR is set
if [ -z "$DCSTOOL_USERDIR" ]
then
  DCSTOOL_USERDIR=$HOME/.opendcs
fi
export DCSTOOL_USERDIR

if [ ! -d "$DCSTOOL_USERDIR" ]; then
    echo "Creating Local User Directory and initial properties in ${DCSTOOL_USERDIR}" 1>&2
    echo "The default XML database has been copied to this directory." 1>&2
    mkdir -p $DCSTOOL_USERDIR
    cp $DH/decodes.properties $DCSTOOL_USERDIR/user.properties
    cp -r $DH/edit-db $DCSTOOL_USERDIR/edit-db
fi

# Build classpath
CP=$DH/bin/opendcs.jar

# If a user-specific 'dep' (dependencies) directory exists, then
# add all the jars therein to the classpath.
if [ "$CP_SHARED_JAR_DIR" != "" ]; then
  CP=$CP:$CP_SHARED_JAR_DIR/*
  echo "The need of the CP_SHARED_JAR_DIR is variable superseded by using a " 1>&2
  echo "DCSTOOL_USERDIR for configuration. Support for this variable will" 1>&2
  echo "be moved in a future release. Please update your configuration." 1>&2
fi

if [ -d "$DCSTOOL_USERDIR/dep" ]; then
  CP=$CP:$DCSTOOL_USERDIR/dep/*:$DCSTOOL_USERDIR/dep
fi
CP=$CP:$DH/dep/*

if [ -z "$DCSTOOL_USERDIR/logback.xml" ]; then
  LOGBACK="$LOGBACK -Dlogback.configurationFile=$DCSTOOL_USERDIR/logback.xml"
else
  LOGBACK="$LOGBACK -Dlogback.configurationFile=$DCSTOOL_HOME/logback.xml"
fi

APP_NAME=$1
LOG_FILE=""
LOG_LEVEL="-DLOG_LEVEL=info"
APP_ARGS=""

# https://stackoverflow.com/a/36475789
_ARGS=("$@")


shift_globally () {
  shift
  _ARGS=("$@")
}
# end https://stackoverflow.com/a/36475789

function handle_arg {
  arg=$1
  if [[ "${arg:0:2}" == "-a" ]]; then
    handle_app $arg "${@:2}"
  elif [[ "${arg:0:2}" == "-d" ]]; then
    handle_debug $arg "${@:2}"
  elif [[ "${arg:0:2}" == "-D" ]]; then
    handle_jvm_prop $arg "${@:2}"
  elif [[ "${arg:0:2}" == "-l" ]]; then
    handle_log $arg "${@:2}"
  else
    APP_ARGS="$APP_ARGS $arg" # pass through
  fi
}

function handle_jvm_prop {
  arg=$1
  prop=$2
  
  if [[ "$arg" == "-D" ]]; then
    shift_globally "${@:2}"
  else
    prop=${arg:2}
  fi
  APP_ARGS="-D$prop $APP_ARGS" # these come before the class name so that the jvm sets them for us.
}


function handle_debug {
    arg=$1
    level=$2
    if [[ "$arg" == "-d" ]]; then # value is in next argument
      shift_globally "${@:2}"
    else
      level=${arg:2}
    fi
    levelStr="info"
    case $level in
      "-2") levelStr="ERROR" ;;
      "-1") levelStr="WARN" ;;
      "0") levelStr="INFO" ;;
      "1") levelStr="DEBUG" ;;
      "2") levelStr="TRACE" ;;
      "3") levelStr="TRACE" ;;
    esac    
    LOG_LEVEL="-DLOG_LEVEL=${levelStr}" 
}

function handle_log {
  arg=$1
  log_file=$2
  if [[ "$arg" == "-l" ]]; then
    shift_globally "${@:2}"
  else
    log_file=${arg:2}
  fi
  LOG_FILE="-DLOG_FILE=${log_file}"
}

function handle_app {
  arg=$1
  APP_NAME=$2
  if [[ "$arg" == "-a" ]]; then
    shift_globally "${@:2}"
  else
    APP_NAME=${arg:2}
  fi
  APP_ARGS="$APP_ARGS -a $APP_NAME" # this one gets used *and* passed through
}

while [[ ${#_ARGS[@]} -gt 0 ]]; do
  arg=${_ARGS[0]}
  shift_globally ${_ARGS[@]}
  if [[ "$arg" == "--" ]]; then # stop trying to special process anything
    break
  elif [[ ${arg:0:1} == "-" ]]; then
    handle_arg $arg "${_ARGS[@]}" # extract our desired elements
  else
    APP_ARGS="$APP_ARGS $arg" # pass through
  fi
done
# remaining args are assumed correct as is and the application will deal
while [[ ${#_ARGS[@]} -gt 0 ]]; do
  APP_ARGS="$APP_ARGS ${_ARGS[0]}"
  shift_globally "${_ARGS[@]}"
done


if [ "${LOGBACK_OVERRIDE+x}" ]; then
  LOGBACK="$LOGBACK_OVERRIDE"
else
  LOGBACK="$LOGBACK -DAPP_NAME=${APP_NAME} $LOG_FILE $LOG_LEVEL"
fi

cmd="java -Xms120m $DECJ_MAXHEAP $DECJ_OPTS -cp $CP -DDCSTOOL_HOME=$DH -DDECODES_INSTALL_DIR=$DH -DDCSTOOL_USERDIR=$DCSTOOL_USERDIR $LOGBACK $APP_ARGS"
echo "cli: $cmd"
exec $cmd
