#!/bin/sh

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

# Source function library. used for "status" use case
if [ -f "/etc/rc.d/init.d/functions" ]; then
  PLATFORM="RHEL"
  . /etc/rc.d/init.d/functions
elif [ -f /lib/lsb/init-functions ] ; then
  PLATFORM="UBUNTU"
  . /lib/lsb/init-functions
else
  PLATFORM="UNSUPPORTED"
fi

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
bin=`dirname "${BASH_SOURCE-$0}"`
bin=`cd "$bin"; pwd`
lib="$bin"/../lib
conf="$bin"/../conf
script=`basename $0`

# Resolve relative symlinks
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/.."
APP_HOME="`pwd -P`"
APP=`basename $0`

# Load component common environment file too
. $bin/tephra-env.sh

pid=$PID_DIR/tephra-service-${IDENT_STRING}.pid

# In other environment, the jars are expected to be in <HOME>/lib directory.
# Load all the jar files. Not ideal, but we need to load only the things that
# is needed by this script.
if [ "$CLASSPATH" = "" ]; then
  CLASSPATH=${lib}/*
else
  CLASSPATH=$CLASSPATH:${lib}/*
fi

# Load the configuration too.
if [ -d "$conf" ]; then
  CLASSPATH=$CLASSPATH:"$conf"/
fi

# Set Log location
if [ ! -e $LOG_DIR ]; then
  mkdir -p $LOG_DIR;
fi
export LOG_PREFIX="tephra-service-$IDENT_STRING-$HOSTNAME"
export LOGFILE=$LOG_PREFIX.log
loglog="${LOG_DIR}/${LOGFILE}"

# set the classpath to include hadoop and hbase dependencies
set_classpath()
{
  COMP_HOME=$1
  if [ -n "$HBASE_HOME" ]; then
    HBASE_CP=`$HBASE_HOME/bin/hbase classpath`
  elif [ `which hbase` ]; then
    HBASE_CP=`hbase classpath`
  fi

  export HBASE_CP

  if [ -n "$HBASE_CP" ]; then
    CP=$COMP_HOME/lib/*:$HBASE_CP:$COMP_HOME/conf/:$EXTRA_CLASSPATH
  else
    # assume Hadoop/HBase libs are included via EXTRA_CLASSPATH
    echo "WARN: could not find Hadoop and HBase libraries"
    CP=$COMP_HOME/lib/*:$COMP_HOME/conf/:$EXTRA_CLASSPATH
  fi

  # Setup classpaths.
  if [ -n "$CLASSPATH" ]; then
    CLASSPATH=$CLASSPATH:$CP
  else
    CLASSPATH=$CP
  fi

  export CLASSPATH
}

# Attempts to find JAVA in few ways.
set_java ()
{
  # Determine the Java command to use to start the JVM.
  if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        export JAVA="$JAVA_HOME/jre/sh/java"
    else
        export JAVA="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVA" ] ; then
        echo "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." >&2
        exit 1
    fi
  else
    export JAVA="java"
    which java >/dev/null 2>&1 || { echo "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." >&2 ; exit 1; }
  fi
}

# checks if there exists a PID that is already running. return 0 idempotently
check_before_start()
{
  if [ ! -d "$PID_DIR" ]; then
    mkdir -p "$PID_DIR"
  fi
  if [ -f $pid ]; then
    if kill -0 `cat $pid` > /dev/null 2>&1; then
      #echo "$APP $SERVICE running as process `cat $pid`. Stop it first."
      echo "$APP running as process `cat $pid`. Stop it first."
      exit 0
    fi
  fi
}

# Set Niceness
if [ "$NICENESS" = "" ]; then
 export NICENESS=0
fi

start() {
  # Setup classpaths.
  set_classpath $APP_HOME

  # sets the JAVA variable.
  set_java

  check_before_start

  echo "`date` Starting $APP service on `hostname`"
  echo "`date` Starting $APP service on `hostname`" >> $loglog
  echo "`ulimit -a`" >> $loglog 2>&1

  export MAIN_CLASS="org.apache.tephra.TransactionServiceMain"
  echo "Running class $MAIN_CLASS"
  echo "Command: " "$JAVA" $OPTS -cp $CLASSPATH $JAVA_HEAPMAX $MAIN_CLASS >>$loglog
  nohup nice -n $NICENESS "$JAVA" $OPTS -cp $CLASSPATH $JAVA_HEAPMAX ${MAIN_CLASS} </dev/null >>$loglog 2>&1 &
  echo $! >$pid
}

stop() {
  if [ -f $pid ]; then
    pidToKill=`cat $pid`
    # kill -0 == see if the PID exists
    if kill -0 $pidToKill > /dev/null 2>&1; then
      echo -n stopping $command
      echo "`date` Terminating $command" >> $loglog
      kill $pidToKill > /dev/null 2>&1
      while kill -0 $pidToKill > /dev/null 2>&1;
      do
        echo -n "."
        sleep 1;
      done
      rm $pid
      echo
    else
      retval=$?
      echo nothing to stop because kill -0 of pid $pidToKill failed with status $retval
    fi
    rm -f $pid
  else
    echo nothing to stop because no pid file $pid
  fi
}

restart() {
    stop
    start
}

condrestart(){
    case "$PLATFORM" in
      "RHEL")
        rh_status > /dev/null 2>&1
        retval=$?
      ;;
      "UBUNTU")
        ub_status > /dev/null 2>&1
        retval=$?
      ;;
      "UNSUPPORTED")
        echo "condrestart is not supported on platform"
        exit 1
      ;;
    esac

  if [[ $retval -eq 0 ]]; then
    restart
  fi
}

rh_status() {
    echo "checking status"
    # call sourced status function
    status -p $pid 
}

ub_status() {
    echo "checking status"
    # call sourced status function
    status_of_proc -p $pid "$0" "$APP"
}

# Executes a specific class' main method with the classpath and environment setup
run() {
    classname=$1
    shift
    if [ -z "$classname" ]; then
        echo "ERROR: No classname was given!"
        echo "Usage: $0 run <fully qualified classname> [arguments]"
        exit 1
    fi
    # Setup classpaths.
    set_classpath $APP_HOME

    # sets the JAVA variable.
    set_java

    echo "Running class $classname"
    "$JAVA" $OPTS -cp $CLASSPATH $JAVA_HEAPMAX $classname $@
}

case "$1" in
  start)
    $1  
  ;;
  
  stop)
    $1
  ;;

  restart)
    $1
  ;;

  condrestart)
    $1
  ;;

  status)
    case "$PLATFORM" in
      "RHEL")
        rh_status
      ;;
      "UBUNTU")
        ub_status
      ;;
      "UNSUPPORTED")
        echo "status is not supported on platform"
        exit 1
      ;;
    esac 
  ;;

  classpath)
    set_classpath $APP_HOME
    set_java
    echo $CLASSPATH
  ;;

  run)
    shift
    run $@
  ;;

  *)
    echo "Usage: $0 {start|stop|restart|status|run}"
    exit 1
  ;;


esac
exit $? 

