#! /usr/bin/env bash
#
# Copyright (c) 2013-%%copyright.year%% Commonwealth Computer Research, Inc.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0 which
# accompanies this distribution and is available at
# https://www.apache.org/licenses/LICENSE-2.0
#

# set environment variables in conf/geomesa-env.sh, dependencies in .dependencies

# configure HOME and CONF_DIR, then load geomesa-env.sh
localHomeDir="$(cd "$(dirname "$0")"/.. || exit; pwd)"
export %%tools.dist.name%%_HOME="${%%tools.dist.name%%_HOME:-$localHomeDir}"
if [[ ! "$%%tools.dist.name%%_HOME" -ef "$localHomeDir" ]]; then
  echo >&2 "ERROR: %%tools.dist.name%%_HOME is pointing to ${%%tools.dist.name%%_HOME}, but script is being invoked from ${localHomeDir}/bin"
  exit 1
fi
if [[ -n "$GEOMESA_CONF_DIR" ]] &&  [[ ! "$GEOMESA_CONF_DIR" -ef "$%%tools.dist.name%%_HOME/conf" ]]; then
  echo >&2 "ERROR: GEOMESA_CONF_DIR is pointing to $GEOMESA_CONF_DIR, instead of ${%%tools.dist.name%%_HOME}/conf"
  exit 1
fi
export GEOMESA_CONF_DIR="${%%tools.dist.name%%_HOME}/conf"

NG_RUNNER="org.locationtech.geomesa.tools.utils.NailgunServer"

source "${GEOMESA_CONF_DIR}/geomesa-env.sh"
source "${GEOMESA_CONF_DIR}/functions.sh"

# create log dir if needed
if [[ ! -d "${GEOMESA_LOG_DIR}" ]]; then
  mkdir -p "${GEOMESA_LOG_DIR}"
fi

if [[ $1 = debug ]]; then
  GEOMESA_OPTS="${GEOMESA_OPTS} ${GEOMESA_DEBUG_OPTS}"
  shift 1
fi

function load_classpath() {
  CLASSPATH="$(get_classpath)"
  # load and check required dependencies - skip if classpath is explicitly set
  if [[ -z "$GEOMESA_CLASSPATH" && "$GEOMESA_CHECK_DEPENDENCIES" = "true" && -f "${GEOMESA_CONF_DIR}/dependencies.sh" ]]; then
    source "${GEOMESA_CONF_DIR}/dependencies.sh"
    includes="$(dependencies "$CLASSPATH")"
    # TODO check for --no-prompt and pass it along
    check_classpath "$GEOMESA_LIB_DIR" "$CLASSPATH" "$includes"
    RET=$?
    if [[ $RET -eq 1 ]]; then
      # downloaded new jars - re-load the classpath to pick them up
      CLASSPATH="$(get_classpath)"
    elif [[ $RET -ne 0 ]]; then
       # error or cancelled
      exit $RET
    fi
  fi
}

# setup the classpath
function get_classpath() {
  if [[ -n "$GEOMESA_CLASSPATH" ]]; then
    echo "$GEOMESA_CLASSPATH"
  else
    local classpath
    # include geomesa first so that the correct log4j.properties is picked up
    classpath="${GEOMESA_CONF_DIR}:$(find_jars "$GEOMESA_LIB_DIR")"
    # prepend user defined directories to the classpath using java classpath syntax
    # we prepend so that they take precedence when explicitly defined by the user
    if [[ -n "${GEOMESA_EXTRA_CLASSPATHS}" ]]; then
      classpath="${GEOMESA_EXTRA_CLASSPATHS}:${classpath}"
    fi
    for file in "${GEOMESA_CONF_DIR}"/*-env.sh; do
      if [[ -f "$file" ]] && [[ "$file" != "${GEOMESA_CONF_DIR}"/geomesa-env.sh ]]; then
        local env_cp
        env_cp="$(source "$file")"
        classpath="$classpath:$(remove_slf4j_from_classpath "$env_cp")"
      fi
    done
    classpath="$(remove_log4j1_from_classpath "$classpath")"
    classpath="$(fix_classpath_format "$classpath")"
    echo "$classpath"
  fi
}

function start_nailgun() {
  load_classpath
  local NG_OPTS=()
  if [[ -n "$GEOMESA_NG_SERVER" ]]; then
    NG_OPTS+=("-host" "$GEOMESA_NG_SERVER")
  fi
  if [[ -n "$GEOMESA_NG_PORT" ]]; then
    NG_OPTS+=("--port" "$GEOMESA_NG_PORT")
  fi
  if [[ -n "$GEOMESA_NG_TIMEOUT" ]]; then
    NG_OPTS+=("--timeout" "$GEOMESA_NG_TIMEOUT")
  fi
  if [[ -n "$GEOMESA_NG_IDLE" ]]; then
    NG_OPTS+=("--idle" "$GEOMESA_NG_IDLE")
  fi
  if [[ -n "$GEOMESA_NG_POOL_SIZE" ]]; then
    NG_OPTS+=("--pool-size" "$GEOMESA_NG_POOL_SIZE")
  fi
  echo -n "Starting Nailgun server... " >&2
  # create a named pipe to read our nailgun startup output
  fd="$(mktemp --tmpdir ngfdXXXX)" && rm "$fd" && mkfifo "$fd"
  exec 3<>"$fd" # tie the pipe to output 3
  rm "$fd" # remove the pipe so that the process can exit normally
  # start nailgun in the background and redirect output to the pipe
  # shellcheck disable=SC2086
  nohup java $GEOMESA_OPTS -cp "$CLASSPATH" $NG_RUNNER "${NG_OPTS[@]}" >&3 2>&1 </dev/null &
  # read the output from the nailgun start up, timeout after 60 seconds
  read -t 60 -r ng_output <&3
  echo "$ng_output" >&2
  if ! echo "$ng_output" | grep -q started; then
    echo "Error starting Nailgun server" >&2
    exit 1
  fi
}


if [[ $1 = classpath ]]; then
  get_classpath | tr ':' '\n' | sort
elif [[ $1 = configure ]]; then
  geomesa_configure
elif [[ $1 = scala-console ]]; then
  shift 1
  load_classpath
  # scala console requires options to be passed in through java_opts
  export JAVA_OPTS="${GEOMESA_OPTS}"
  geomesa_scala_console "$(get_classpath)" "$@"
elif [[ $1 = ng && $2 = start ]]; then
  start_nailgun
elif [[ $1 = ng && $2 = stop ]]; then
  "${%%tools.dist.name%%_HOME}"/bin/ng ng-stop
elif [[ $1 = ng && $2 = classpath ]]; then
  "${%%tools.dist.name%%_HOME}"/bin/ng ng-cp
elif [[ "$GEOMESA_NG_ENABLED" = "true" ]]; then
  # check to see if the nailgun server is up
  "${%%tools.dist.name%%_HOME}"/bin/ng ng-version >/dev/null 2>&1
  RET=$?
  if [[ $RET -ne 0 ]]; then
    # it's not running, start the nailgun server
    start_nailgun
  fi
  # invoke the nailgun client
  "${%%tools.dist.name%%_HOME}"/bin/ng "%%tools.runner%%" "$@"
else
  load_classpath
  # shellcheck disable=SC2086
  java $GEOMESA_OPTS -cp "$CLASSPATH" "%%tools.runner%%" "$@"
fi
