#!/usr/bin/env 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 Chukwa command script
#
# Environment Variables
#
#   JAVA_HOME        The java implementation to use.  Overrides JAVA_HOME.
#   CHUKWA_CONF_DIR  Alternate conf dir.  Default is ${CHUKWA_HOME}/conf.
#

bin=`dirname "$0"`
bin=`cd "$bin"; pwd`

. "$bin"/../libexec/chukwa-config.sh

# if no args specified, show usage
if [ $# = 0 ]; then
  echo "Usage: chukwa [--config confdir] COMMAND"
  echo "where COMMAND is one of:"
  echo "  agent         run a Chukwa Agent"
  echo "  archive       run the Archive Manager"
  echo "  demux         run the Demux Manager"
  echo "  dp            run the Post Demux data processors"
  echo "  hicc          run a HICC Webserver"
  echo "  droll         run a daily rolling job (deprecated)"
  echo "  hroll         run a hourly rolling job (deprecated)"
  # Daily rolling and hourly rolling will be deprecated by retention processor
  # echo "  retention     run the Retention Processor"
  echo "  version       print the version"
  echo "Utilities:"
  echo "  backfill      run a back fill data loader utility"
  echo "  dumpArchive   view an archive file"
  echo "  dumpRecord    view a record file"
  echo "  tail          start tailing a file"
  echo "Most command print help when invoked w/o parameters."
  exit 1
fi

# get arguments
COMMAND=$1
shift

if [ -f "${CHUKWA_CONF_DIR}/chukwa-env.sh" ]; then
  . "${CHUKWA_CONF_DIR}/chukwa-env.sh"
fi

# Java parameters
if [ "$JAVA_HOME" != "" ]; then
  JAVA_HOME=$JAVA_HOME
fi

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

if [ "$HADOOP_CONF_DIR" != "" ]; then
  CLASSPATH=${HADOOP_CONF_DIR}:${CLASSPATH}
fi

if [ "$CHUKWA_HICC_PORT" = "" ]; then
  CHUKWA_HICC_PORT=4080
fi

if [ "$CHUKWA_STOP_TIMEOUT" = "" ]; then
  CHUKWA_STOP_TIMEOUT=3
fi

# configure command parameters
if [ "$COMMAND" = "agent" ]; then
  APP='agent'
  CLASS='org.apache.hadoop.chukwa.datacollection.agent.ChukwaAgent'
elif [ "$COMMAND" = "archive" ]; then
  APP='archive'
  CLASS='org.apache.hadoop.chukwa.extraction.archive.ChukwaArchiveManager'
elif [ "$COMMAND" = "dp" ]; then
  APP='postprocess'
  CLASS='org.apache.hadoop.chukwa.extraction.demux.PostProcessorManager'
elif [ "$COMMAND" = "demux" ]; then
  APP='Demux'
  CLASS='org.apache.hadoop.chukwa.extraction.demux.DemuxManager'
elif [ "$COMMAND" = "hicc" ]; then
  WEB_SERVICE_COMMON=`ls ${CHUKWA_HOME}/share/chukwa/webapps/hicc.war`
  APP='hicc'
  CLASS='org.apache.hadoop.chukwa.hicc.HiccWebServer'
  CLASSPATH=${CLASSPATH}:${WEB_SERVICE_COMMON}:${HICC_JAR}
  HOST=`hostname`
  JAVA_OPT="${JAVA_OPT} -Djetty.host=${HOST} -Djetty.port=${CHUKWA_HICC_PORT} -Djava.net.preferIPv4Stack=true"
elif [ "$COMMAND" = "hroll" ]; then
  APP='hroll'
  CLASS='org.apache.hadoop.chukwa.extraction.demux.HourlyChukwaRecordRolling'
  OPTS='rollInSequence true deleteRawdata true'
elif [ "$COMMAND" = "droll" ]; then
  APP='droll'
  CLASS='org.apache.hadoop.chukwa.extraction.demux.DailyChukwaRecordRolling'
  OPTS='rollInSequence true deleteRawdata true'
elif [ "$COMMAND" = "version" ]; then
  echo `cat ${CHUKWA_HOME}/bin/VERSION`
  exit 0
elif [ "$COMMAND" = "backfill" ]; then
  APP='backfill'
  CLASS='org.apache.hadoop.chukwa.tools.backfilling.BackfillingLoader'
elif [ "$COMMAND" = "dumpArchive" ]; then
  APP='DumpArchive'
  CLASS='org.apache.hadoop.chukwa.util.DumpArchive'
  BACKGROUND="false"
elif [ "$COMMAND" = "dumpRecord" ]; then
  APP='DumpRecord'
  CLASS='org.apache.hadoop.chukwa.util.DumpRecord'
  BACKGROUND="false"
elif [ "$COMMAND" = "dumpChunk" ]; then
  APP='DumpChunk'
  CLASS='org.apache.hadoop.chukwa.util.DumpChunks'
  BACKGROUND="false"
elif [ "$COMMAND" = "tail" ]; then
  if [ $# = 0 -o $# -gt 2 ]; then
    echo "usage: startWatchingFile <filename> [datatype]"
    exit 1
  fi

  filename=$1

  if [ $# -ge 2 ]; then
    datatype=$2
  else
    datatype=raw
  fi
  echo "tailing $datatype: $filename"
  echo "add org.apache.hadoop.chukwa.datacollection.adaptor.filetailer.CharFileTailingAdaptorUTF8  $datatype 0  $filename  0" | nc localhost 9093
  exit 0
fi

pid="$CHUKWA_PID_DIR/chukwa-$CHUKWA_IDENT_STRING-$COMMAND.pid"

if [ "$1" = "start" ]; then
  shift
  if [ -f $pid ]; then
    TARGET_PID=`cat $pid`
    if kill -0 `cat $pid` > /dev/null 2>&1; then
      if [ $TARGET_PID == $$ ]; then
        # run command
        exec ${JAVA_HOME}/bin/java ${JAVA_OPT} \
          -Djava.library.path=${JAVA_LIBRARY_PATH} \
          -DCHUKWA_HOME=${CHUKWA_HOME} \
          -DCHUKWA_CONF_DIR=${CHUKWA_CONF_DIR} \
          -DCHUKWA_LOG_DIR=${CHUKWA_LOG_DIR} \
          -DCHUKWA_DATA_DIR=${CHUKWA_DATA_DIR} \
          -DAPP=${APP} -Dlog4j.configuration=chukwa-log4j.properties \
          -classpath ${CHUKWA_CONF_DIR}:${CLASSPATH}:${CHUKWA_CLASSPATH}:${tools} ${CLASS} $OPTS $@
      else 
        echo $COMMAND running as process `cat $pid`.  Stop it first.
        exit 1
      fi
    else
      echo $COMMAND is not running, but found pid file $pid.
      exit 1
    fi
  fi
fi

if [ "$1" = "stop" ]; then
  if [ -f $pid ]; then
    TARGET_PID=`cat $pid`
    if kill -0 $TARGET_PID > /dev/null 2>&1; then
      kill -TERM $TARGET_PID
      sleep $CHUKWA_STOP_TIMEOUT
      if kill -0 $TARGET_PID > /dev/null 2>&1; then
        kill -9 $TARGET_PID
        exit 1
      fi
    fi
  else 
    echo "Cannot find PID file - $pid.pid; NO $COMMAND to stop";
  fi
  exit 0
fi

