#! /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
  manager     Accumulo manager
  master      Accumulo master (Deprecated)
  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 == "manager" ]]; then
    "${bin}/accumulo" org.apache.accumulo.manager.state.SetGoalState NORMAL
  fi

  outfile="${ACCUMULO_LOG_DIR}/${service}${ACCUMULO_SERVICE_INSTANCE}_${host}.out"
  errfile="${ACCUMULO_LOG_DIR}/${service}${ACCUMULO_SERVICE_INSTANCE}_${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}"
  ACCUMULO_PID_DIR="${ACCUMULO_PID_DIR:-${basedir}/run}"

  mkdir -p "$ACCUMULO_LOG_DIR" 2>/dev/null
  mkdir -p "$ACCUMULO_PID_DIR" 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"

  if [[ $service == "master" ]]; then
    echo "WARN : Use of 'master' service name is deprecated; use 'manager' instead."
    service="manager"
  fi

  pid_file="${ACCUMULO_PID_DIR}/accumulo-${service}${ACCUMULO_SERVICE_INSTANCE}.pid"
  case "$service" in
    gc|manager|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 "$@"
