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

function print_usage {
  cat <<EOF
Usage: accumulo-service <service> <command>

Services:
  gc          Accumulo garbage collector
  monitor     Accumulo monitor
  master      Accumulo master
  tserver     Accumulo tserver
  tracer      Accumulo tracter

Commands:
  start       Starts service
  stop        Stops service
  kill        Kills service

EOF
  exit 1
}

function invalid_args {
  echo -e "Invalid arguments: $1\n"
  print_usage 1>&2
  exit 1
}

function rotate_log () {
  logfile="$1"
  max_retained="5"
  if [ -f "$logfile" ]; then
    while [[ "$max_retained" -gt 1 ]]; do
      prev=$(( max_retained - 1))
      [ -f "$logfile.$prev" ] && mv -f "$logfile.$prev" "$logfile.$max_retained"
      max_retained=$prev
    done
    mv -f "$logfile" "$logfile.$max_retained";
  fi
}

function start_service() {
  if [ -f "$pid_file" ]; then
    pid=$(cat "$pid_file")
    if kill -0 "$pid" 2>/dev/null; then
      echo "$host : $service already running (${pid})"
      exit 0
    fi
  fi
  echo "Starting $service on $host"

  if [[ $service == "master" ]]; then
    "${bin}/accumulo" org.apache.accumulo.master.state.SetGoalState NORMAL
  fi

  outfile="${ACCUMULO_LOG_DIR}/${service}_${host}.out"
  errfile="${ACCUMULO_LOG_DIR}/${service}_${host}.err"
  rotate_log "$outfile"
  rotate_log "$errfile"

  nohup "${bin}/accumulo" "$service" >"$outfile" 2>"$errfile" < /dev/null &
  echo "$!" > "${pid_file}"

  # Check the max open files limit and selectively warn
  max_files_open=$(ulimit -n)
  if [[ -n $max_files_open ]] ; then
    max_files_recommended=32768
    if (( max_files_open < max_files_recommended )); then
      echo "WARN : Max open files on $host is $max_files_open, recommend $max_files_recommended" >&2
    fi
  fi
}

function stop_service() {
  if [ -f "$pid_file" ]; then
    echo "Stopping $service on $host";
    kill -s TERM "$(cat "$pid_file")" 2>/dev/null
    rm -f "${pid_file}" 2>/dev/null
  fi
}

function kill_service() {
  if [ -f "$pid_file" ]; then
    echo "Killing $service on $host";
    kill -s KILL "$(cat "$pid_file")" 2>/dev/null
    rm -f "${pid_file}" 2>/dev/null
  fi
}

function main() {
  if [[ -z $1 ]]; then
    invalid_args "<service> cannot be empty"
  fi

  # Resolve base directory
  SOURCE="${BASH_SOURCE[0]}"
  while [ -h "${SOURCE}" ]; do
     bin="$( cd -P "$( dirname "${SOURCE}" )" && pwd )"
     SOURCE="$(readlink "${SOURCE}")"
     [[ "${SOURCE}" != /* ]] && SOURCE="${bin}/${SOURCE}"
  done
  # Set up variables needed by accumulo-env.sh
  export bin="$( cd -P "$( dirname "${SOURCE}" )" && pwd )"
  export basedir=$( cd -P "${bin}"/.. && pwd )
  export conf="${ACCUMULO_CONF_DIR:-${basedir}/conf}"
  export lib="${basedir}/lib"

  if [ -f "${conf}/accumulo-env.sh" ]; then
    source "${conf}/accumulo-env.sh"
  fi
  ACCUMULO_LOG_DIR="${ACCUMULO_LOG_DIR:-${basedir}/logs}"

  mkdir -p "$ACCUMULO_LOG_DIR" 2>/dev/null
  mkdir -p "${basedir}/run" 2>/dev/null

  host="$(hostname)"
  if [[ -z "$host" ]]; then
    host=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1  -d'/')
  fi 
  service="$1"
  pid_file="${basedir}/run/accumulo-${service}.pid"
  case "$service" in
    gc|master|monitor|tserver|tracer)
      if [[ -z $2 ]]; then
        invalid_args "<command> cannot be empty"
      fi
      case "$2" in 
        start)
          start_service
          ;;
        stop)
          stop_service
          ;;
        kill)
          kill_service
          ;;
        *)
          invalid_args "'$2' is an invalid <command>"
          ;;
      esac
      ;;
    *)
      invalid_args "'$service' is an invalid <service>"
      ;;
  esac
}

main "$@"
