#!/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.


##
# The script to run Java components.
#
# Environment Variables
#
#   GORA_HEAPSIZE  The maximum amount of heap to use, in MB. 
#                   Default is 1024.
#
#   GORA_OPTS      Extra Java runtime option.
#

# resolve links - $0 may be a softlink
THIS="$0"
while [ -h "$THIS" ]; do
  ls=`ls -ld "$THIS"`
  link=`expr "$ls" : '.*-> \(.*\)$'`
  if expr "$link" : '.*/.*' > /dev/null; then
    THIS="$link"
  else
    THIS=`dirname "$THIS"`/"$link"
  fi
done

# if no args specified, show usage
if [ $# = 0 ]; then
  echo "Usage: run COMMAND [COMMAND options]"
  echo "where COMMAND is one of:"
  echo "  goracompiler               Run Compiler"
  echo "  specificcompiler           Run Avro Specific Compiler"
  echo "  cassandranativecompiler    Run Gora Cassandra Native Compiler"
  echo "  dynamocompiler             Run Gora DynamoDB Compiler"
  echo "  goracirackspace            Run the GoraCI Rackspace orchestration setup"
  echo "  goracichef                 Run the GoraCI Chef software provisioning setup"
  echo "  logmanager                 Run the tutorial log manager"
  echo "  distributedlogmanager      Run the tutorial distributed log manager"
  echo "  loganalytics               Run the tutorial log analytics"
  echo "  loganalyticsspark          Run the tutorial log analytics spark"
  echo "  junit         	     Run the given JUnit test"
  echo "  version         	     Print Gora version to terminal"
  echo " or"
  echo " MODULE CLASSNAME   run the class named CLASSNAME in module MODULE"
  echo "Most commands print help when invoked w/o parameters."
  exit 1
fi

# get arguments
COMMAND=$1
shift

# some directories
THIS_DIR=`dirname "$THIS"`
GORA_HOME=`cd "$THIS_DIR/.." ; pwd`

if [ -f "${GORA_HOME}/conf/gora-env.sh" ]; then
  . "${GORA_HOME}/conf/gora-env.sh"
fi

if [ "$JAVA_HOME" = "" ]; then
  echo "Error: JAVA_HOME is not set."
  exit 1
fi

JAVA=$JAVA_HOME/bin/java
JAVA_HEAP_MAX=-Xmx1024m 

# check envvars which might override default args
if [ "$GORA_HEAPSIZE" != "" ]; then
  #echo "run with heapsize $GORA_HEAPSIZE"
  JAVA_HEAP_MAX="-Xmx""$GORA_HEAPSIZE""m"
  #echo $JAVA_HEAP_MAX
fi

# CLASSPATH initially contains $GORA_CONF_DIR, or defaults to $GORA_HOME/conf
CLASSPATH=${GORA_CONF_DIR:=$GORA_HOME/conf}
CLASSPATH=${CLASSPATH}:$JAVA_HOME/lib/tools.jar

# so that filenames w/ spaces are handled correctly in loops below
IFS=

# restore ordinary behaviour
unset IFS

# default log directory & file
if [ "$GORA_LOG_DIR" = "" ]; then
  GORA_LOG_DIR="$GORA_HOME/logs"
fi
if [ "$GORA_LOGFILE" = "" ]; then
  GORA_LOGFILE='gora.log'
fi

if [ "x$JAVA_LIBRARY_PATH" != "x" ]; then
  JAVA_OPTS="$JAVA_OPTS -Djava.library.path=$JAVA_LIBRARY_PATH"
fi

#GORA_OPTS="$GORA_OPTS -Dhadoop.log.dir=$GORA_LOG_DIR"
#GORA_OPTS="$GORA_OPTS -Dhadoop.log.file=$GORA_LOGFILE"

# figure out which class to run
if [ "$COMMAND" = "goracompiler" ] ; then
  MODULE=gora-compiler-cli
  CLASSPATH=$CLASSPATH:$GORA_HOME/$MODULE/target/classes/
  CLASS=org.apache.gora.compiler.cli.GoraCompilerCLI
elif [ "$COMMAND" = "specificcompiler" ] ; then
  MODULE=gora-core
  CLASSPATH=$CLASSPATH:$GORA_HOME/$MODULE/target/classes/
  CLASS=org.apache.avro.specific.SpecificCompiler
elif [ "$COMMAND" = "cassandranativecompiler" ] ; then
  MODULE=gora-cassandra-cql
  CLASSPATH=$CLASSPATH:$GORA_HOME/$MODULE/target/classes/
  CLASS=org.apache.gora.cassandra.compiler.GoraCassandraNativeCompiler
elif [ "$COMMAND" = "dynamocompiler" ] ; then
  MODULE=gora-dynamodb
  CLASSPATH=$CLASSPATH:$GORA_HOME/$MODULE/target/classes/
  CLASS=org.apache.gora.dynamodb.compiler.GoraDynamoDBCompiler
elif [ "$COMMAND" = "goracirackspace" ] ; then
  MODULE=gora-goraci
  CLASSPATH=$CLASSPATH:$GORA_HOME/$MODULE/target/classes/
  CLASS=org.apache.gora.goraci.rackspace.RackspaceOrchestration
elif [ "$COMMAND" = "goracichef" ] ; then
  MODULE=gora-goraci
  CLASSPATH=$CLASSPATH:$GORA_HOME/$MODULE/target/classes/
  CLASS=org.apache.gora.goraci.chef.ChefSoftwareProvisioning
elif [ "$COMMAND" = "logmanager" ] ; then
  MODULE=gora-tutorial
  CLASSPATH=$CLASSPATH:$GORA_HOME/$MODULE/target/classes/
  CLASS=org.apache.gora.tutorial.log.LogManager
elif [ "$COMMAND" = "distributedlogmanager" ] ; then
  MODULE=gora-tutorial
  CLASSPATH=$CLASSPATH:$GORA_HOME/$MODULE/target/classes/
  CLASS=org.apache.gora.tutorial.log.DistributedLogManager
elif [ "$COMMAND" = "loganalytics" ] ; then
  MODULE=gora-tutorial
  CLASS=org.apache.gora.tutorial.log.LogAnalytics
  CLASSPATH=$CLASSPATH:$GORA_HOME/$MODULE/target/classes/
elif [ "$COMMAND" = "loganalyticsspark" ] ; then
  MODULE=gora-tutorial
  CLASS=org.apache.gora.tutorial.log.LogAnalyticsSpark
  CLASSPATH=$CLASSPATH:$GORA_HOME/$MODULE/target/classes/
elif [ "$COMMAND" = "junit" ] ; then
  MODULE=*
  CLASSPATH=$CLASSPATH:$GORA_HOME/$MODULE/target/test-classes/
  CLASS=junit.textui.TestRunner
elif [ "$COMMAND" = "version" ] ; then
  MODULE=gora-core
  CLASSPATH=$CLASSPATH:$GORA_HOME/$MODULE/target/classes/
  CLASS=org.apache.gora.util.VersionInfo
else
  MODULE="$COMMAND"
  CLASS=$1
  shift
fi

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
# add libs to CLASSPATH
for f in $GORA_HOME/$MODULE/lib/*.jar; do
  CLASSPATH=${CLASSPATH}:$f;
done

for f in $GORA_HOME/$MODULE/target/*.jar; do
  CLASSPATH=${CLASSPATH}:$f;
done
IFS=$SAVEIFS

CLASSPATH=${CLASSPATH}:$GORA_HOME/$MODULE/target/classes/
CLASSPATH=${CLASSPATH}:$GORA_HOME/$MODULE/target/test-classes/

CLASSPATH=${CLASSPATH}:$GORA_HOME/conf
CLASSPATH=${CLASSPATH}:$GORA_HOME/$MODULE/conf

# run it
exec "$JAVA" $JAVA_HEAP_MAX $JAVA_OPTS $GORA_OPTS -classpath "$CLASSPATH" $CLASS "$@"
