#!/usr/bin/env bash

# Copyright (c) 2015, Percona LLC and/or its affiliates. All rights reserved.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>

set -ue

BASEDIR="${BASEDIR:-"/usr/local/percona/qan-app"}"
LISTEN="${LISTEN:-"0.0.0.0:8000"}"
HOST="${LISTEN%:*}"
PORT="${LISTEN#*:}"
CHECK_REQ="${CHECK_REQ:-"yes"}"
START="${START:-"yes"}"
SYSINT="${SYSINT:-"yes"}"

BIN="percona-qan-app"
INIT_SCRIPT="/etc/init.d/$BIN"
KERNEL=`uname -s`

err() {
   echo "ERROR: $*" >&2
   exit 1
}

usage() {
   echo "Usage: $0 [command]"
   echo
   echo "Commands:"
   echo "  check    Check requirements"
   echo "  help     Print this"
   echo
   echo "Environment variables:"
   echo "  BASEDIR    ($BASEDIR)"
   echo "  LISTEN     ($LISTEN)"
   echo "  START      ($START)"
   echo "  SYSINT     ($SYSINT)"
}

app_is_running() {
   APP_PID=$(ps ax | grep "$BIN-$PORT" | grep -v grep | awk '{print $1}')
   [ "$APP_PID" ] && return 0 # running
   return 1 # not running
}

run_app() {
   if [ "$KERNEL" != "Darwin" ]; then
      "$INIT_SCRIPT" start
   else
      "$BASEDIR/start"
   fi
   if [ $? -ne 0 ]; then
      err "$BIN did not start, check $BASEDIR/$BIN.log"
   else
      if [ "$HOST" = "0.0.0.0" ]; then
         echo
         echo "WARNING: Percona QAN app is listening on all interfaces ($LISTEN). This could be a security risk." \
            "To listen on a specific interface, reinstall and specify LISTEN=<interface IP>:<port>. For example:" \
            "LISTEN=10.0.0.1:8000 ./install"
         echo
         sleep 1
      fi
      echo "Started Percona QAN App on $LISTEN. To check its log file:"
      echo
      echo "  tail -f $BASEDIR/$BIN.log"
      echo
   fi
}

check_req() {
   echo "Checking requirements..."

   # 'python --version' prints to stderr, which is silly imho, because if we
   # 2>&1 and check that we might false-positive on "command not found".
   if [ -z "$(which python)" ]; then
      echo
      echo "Python is not installed or in the PATH." >&2
      return 1
   else
      echo "OK: Python is installed"
   fi

   if [ "$KERNEL" != "Linux" -a "$KERNEL" != "Darwin" ]; then
      echo
      echo "Linux or Mac OS required, detected $KERNEL" >&2
      return 1
   else
      echo "OK: Linux or Mac OS"
   fi

   return 0
}

# ###########################################################################
# Execution starts here
# ###########################################################################

SCRIPT_DIR="$(dirname $0)"
cd "$SCRIPT_DIR"

if [ $# -eq 0 ]; then
   # Check system requirements, best effort to ensure install will succeed.
   if [ "$CHECK_REQ" = "yes" ]; then
      check_req || exit 1
   fi

   if app_is_running; then
      kill $APP_PID
      [ -f "$BASEDIR/$BIN.pid" ] && rm -f "$BASEDIR/$BIN.pid"
   fi

   if [ ! -d "$BASEDIR" ]; then
      mkdir -p "$BASEDIR" || err "Cannot create $BASEDIR"
   fi

   # Test privs on the basedir, else cp -r will spew errors.
   touch "$BASEDIR/fipar" || err "Cannot write to $BASEDIR"
   rm "$BASEDIR/fipar"    || err "fipar cannot be removed"

   cp -r * "$BASEDIR"
   rm "$BASEDIR/install"
   rm "$BASEDIR/$BIN"

   sed -e "s/:LISTEN/$LISTEN/g" "./start" > "$BASEDIR/start"

   # Register the init script to make "service percona-qan-app start|stop" work.
   if [ "$SYSINT" = "yes" ]; then
      if [ "$KERNEL" != "Darwin" ]; then
         cp -f "./$BIN" "$INIT_SCRIPT"
         chmod a+x "$INIT_SCRIPT"

         if hash update-rc.d 2>/dev/null; then
            echo "Using update-rc.d to install $BIN service"
            update-rc.d $BIN defaults >/dev/null
         elif hash chkconfig 2>/dev/null; then
            echo "Using chkconfig to install $BIN service"
            chkconfig $BIN on >/dev/null
         else
            echo "Cannot find chkconfig or update-rc.d. $BIN is installed," \
               "but it will not start automatically when the server start." \
               "To start it manually, run: $BASEDIR/start" >&2
         fi
      else
         echo "Mac OS detected, not installing sys-init script"
      fi
   fi

   if [ "$START" = "yes" ]; then
      run_app
   fi
elif [ $# -eq 1 ]; then
   case $1 in
      help)
         usage
         exit 0
         ;;
      check)
         if check_req; then
            exit 0
         else
            exit 1
         fi
         ;;
      *)
         echo "Unknown command: '$1'" >&2
         echo "Run without arguments to list commands." >&2
         exit 1
         ;;
   esac
else
   usage
   exit 1
fi
