#!/bin/bash
#
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

################################
# constants
################################

AUDIT_AGENT_CLASS="org.apache.inlong.audit.node.Application"

CLEAN_FLAG=1
################################
# functions
################################

info() {
  if [ ${CLEAN_FLAG} -ne 0 ]; then
    local msg=$1
    echo "Info: $msg" >&2
  fi
}

warn() {
  if [ ${CLEAN_FLAG} -ne 0 ]; then
    local msg=$1
    echo "Warning: $msg" >&2
  fi
}

error() {
  local msg=$1
  local exit_code=$2

  echo "Error: $msg" >&2

  if [ -n "$exit_code" ] ; then
    exit $exit_code
  fi
}

display_help() {
  cat <<EOF
Usage: $0 <command> [options]...

commands:
  help                  display this help text
  agent                 run a audit agent

global options:
  --conf,-c <conf>      use configs in <conf> directory
  --classpath,-C <cp>   append to the classpath
  -Dproperty=value      sets a JDK system property value

agent options:
  --conf-file,-f <file> specify a config file (required)
  --name,-n <name>      the name of this agent (required)
  --help,-h             display help text

Note that if <conf> directory is specified, then it is always included first
in the classpath.

EOF
}

run_audit() {
  local AUDIT_APPLICATION_CLASS

  if [ "$#" -gt 0 ]; then
    AUDIT_APPLICATION_CLASS=$1
    shift
  else
    error "Must specify audit application class" 1
  fi

  if [ ${CLEAN_FLAG} -ne 0 ]; then
    set -x
  fi
  $EXEC $JAVA_HOME/bin/java $JAVA_OPTS -cp "$AUDIT_CLASSPATH" -Daudit.log.path=$LOG_PATH -Djava.library.path=$AUDIT_JAVA_LIBRARY_PATH "$AUDIT_APPLICATION_CLASS" $*
}

################################
# main
################################

# set default params
AUDITE_CLASSPATH=""
JAVA_OPTS="-XX:SurvivorRatio=6"

if [ -z "$AUDIT_JVM_HEAP_OPTS" ]; then
  HEAP_OPTS="-Xms512m -Xmx1024m"
else
  HEAP_OPTS="$AUDIT_JVM_HEAP_OPTS"
fi
JAVA_OPTS="${JAVA_OPTS} ${HEAP_OPTS}"

opt_conf=""
opt_classpath=""
opt_dryrun=""

mode=$1
shift

case "$mode" in
  help)
    display_help
    exit 0
    ;;
  agent)
    opt_agent=1
    ;;
  node)
    opt_agent=1
    warn "The \"node\" command is deprecated. Please use \"agent\" instead."
    ;;
  avro-client)
    opt_avro_client=1
    ;;
  version)
   opt_version=1
   CLEAN_FLAG=0
   ;;
  *)
    error "Unknown or unspecified command '$mode'"
    echo
    display_help
    exit 1
    ;;
esac

while [ -n "$*" ] ; do
  arg=$1
  shift

  case "$arg" in
    --conf|-c)
      [ -n "$1" ] || error "Option --conf requires an argument" 1
      opt_conf=$1
      shift
      ;;
    --classpath|-C)
      [ -n "$1" ] || error "Option --classpath requires an argument" 1
      opt_classpath=$1
      shift
      ;;
    --dryrun|-d)
      opt_dryrun="1"
      ;;
    -D*)
      opt_java_props="$opt_java_props $arg"
      ;;
    -X*)
      opt_java_props="$opt_java_props $arg"
      ;;
    *)
      args="$args $arg"
      ;;
  esac
done

# make opt_conf absolute
if [[ -n "$opt_conf" && -d "$opt_conf" ]]; then
  opt_conf=$(cd $opt_conf; pwd)
fi

# allow users to override the default env vars via conf/audit-env.sh
if [ -z "$opt_conf" ]; then
  warn "No configuration directory set! Use --conf <dir> to override."
elif [ -f "$opt_conf/audit-env.sh" ]; then
  info "Sourcing environment configuration script $opt_conf/audit-env.sh"
  source "$opt_conf/audit-env.sh"
fi

# append command-line java options to stock or env script JAVA_OPTS
if [ -n "${opt_java_props}" ]; then
  JAVA_OPTS="${JAVA_OPTS} ${opt_java_props}"
fi

# prepend command-line classpath to env script classpath
if [ -n "${opt_classpath}" ]; then
  if [ -n "${AUDIT_CLASSPATH}" ]; then
    AUDIT_CLASSPATH="${opt_classpath}:${AUDIT_CLASSPATH}"
  else
    AUDIT_CLASSPATH="${opt_classpath}"
  fi
fi

if [ -z "${AUDIT_HOME}" ]; then
  AUDIT_HOME=$(cd $(dirname $0)/..; pwd)
fi

# prepend $AUDIT_HOME/lib jars to the specified classpath (if any)
if [ -n "${AUDIT_CLASSPATH}" ] ; then
  AUDIT_CLASSPATH="${AUDIT_HOME}/lib/*:$AUDIT_CLASSPATH"
else
  AUDIT_CLASSPATH="${AUDIT_HOME}/lib/*"
fi

LOG_PATH="${AUDIT_HOME}/logs"

# find java
if [ -z "${JAVA_HOME}" ] ; then
  warn "JAVA_HOME is not set!"
  # Try to use Bigtop to autodetect JAVA_HOME if it's available
  if [ -e /usr/libexec/bigtop-detect-javahome ] ; then
    . /usr/libexec/bigtop-detect-javahome
  elif [ -e /usr/lib/bigtop-utils/bigtop-detect-javahome ] ; then
    . /usr/lib/bigtop-utils/bigtop-detect-javahome
  fi

  # Using java from path if bigtop is not installed or couldn't find it
  if [ -z "${JAVA_HOME}" ] ; then
    JAVA_DEFAULT=$(type -p java)
    [ -n "$JAVA_DEFAULT" ] || error "Unable to find java executable. Is it in your PATH?" 1
    JAVA_HOME=$(cd $(dirname $JAVA_DEFAULT)/..; pwd)
  fi
fi

# prepend conf dir to classpath
if [ -n "$opt_conf" ]; then
  AUDIT_CLASSPATH="$opt_conf:$AUDIT_CLASSPATH"
fi

# finally, invoke the appropriate command
if [ -n "$opt_agent" ] ; then
  run_audit $AUDIT_AGENT_CLASS $args
else
  error "This message should never appear" 1
fi
exit 0
