#!/bin/bash

usage="Usage: dbapi-daemon.sh (start|stop|status|restart) <standalone|manager|apiServer|gateway> "

# if no args specified, show usage
if [ $# -le 1 ]; then
  echo $usage
  exit 1
fi

startStop=$1
shift
command=$1
shift

echo "Begin $startStop $command......"

BIN_DIR=`dirname $0`
BIN_DIR=`cd "$BIN_DIR"; pwd`
DBAPI_HOME=`cd "$BIN_DIR/.."; pwd`

jvm_env_file=$BIN_DIR/jvm_env.properties
if [ -f "$jvm_env_file" ]; then
  source $jvm_env_file
fi



export DBAPI_PID_DIR=$DBAPI_HOME/pid
export DBAPI_LOG_DIR=$DBAPI_HOME/logs
export GC_LOG_DIR=$DBAPI_LOG_DIR/gc
export DBAPI_CONF_DIR=$DBAPI_HOME/conf
export DBAPI_LIB_DIR=$DBAPI_HOME/lib/

java_library_path=$DBAPI_HOME/bin/

export STOP_TIMEOUT=5

if [ ! -d "$DBAPI_LOG_DIR" ]; then
  mkdir $DBAPI_LOG_DIR
fi

if [ ! -d "$GC_LOG_DIR" ]; then
  mkdir $GC_LOG_DIR
fi

log=$DBAPI_LOG_DIR/dbapi-$command-$HOSTNAME.out
pid=$DBAPI_PID_DIR/dbapi-$command.pid

cd $DBAPI_HOME

service_file=$(ls $DBAPI_LIB_DIR/dbapi-service* 2>/dev/null | head -1)

export LD_LIBRARY_PATH="$java_library_path:$LD_LIBRARY_PATH"
export DBAPI_OPTS="-server -Djava.library.path=$java_library_path -XX:+IgnoreUnrecognizedVMOptions -XX:+DisableAttachMechanism -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xss512k -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:LargePageSizeInBytes=128m -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -XX:+PrintGCDateStamps -Xlog:gc:$GC_LOG_DIR/gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=dump.hprof -XshowSettings:vm $DBAPI_OPTS"

function contain() {
  local array=$1
  for item in ${array[*]}; do
    if [[ $2 =~ ^"${item}-".* ]]; then
      return 0
    fi
  done
  return 1
}

cp=
exclude_jars=()

function generate_classpath() {
  cp=$DBAPI_CONF_DIR
  for tmp in $(ls $DBAPI_LIB_DIR); do
    contain "${exclude_jars[*]}" $tmp
    res=$(echo $?)
    if [ $res = "1" ]; then
      cp=$cp:$DBAPI_LIB_DIR$tmp
    fi
  done
}

function add_extra_jars() {
  EXTRA_LIB=$DBAPI_HOME/extlib/
  if [ ! -d "$EXTRA_LIB" ]; then
    mkdir $EXTRA_LIB
  fi
  for tmp in $(ls $EXTRA_LIB); do
    cp=$cp:$EXTRA_LIB$tmp
  done
}

if [ "$command" = "standalone" ]; then
  exclude_jars=("spring-boot-starter-webflux" "spring-webflux" "spring-cloud-gateway-server" "spring-cloud-starter-gateway")
  generate_classpath
  add_extra_jars
  CLASS=com.gitee.freakchicken.dbapi.CIjAcBwM
  HEAP_OPTS=$standalone_opts
  PROFILES="-Dspring.profiles.active=standalone"
  export DBAPI_OPTS="$HEAP_OPTS $DBAPI_OPTS"

elif [ "$command" = "manager" ]; then
  exclude_jars=("spring-boot-starter-webflux" "spring-webflux" "spring-cloud-gateway-server" "spring-cloud-starter-gateway")
  generate_classpath
  add_extra_jars
  CLASS=com.gitee.freakchicken.dbapi.manager.JsoHGkKg
  HEAP_OPTS=$manager_opts
  PROFILES="-Dspring.profiles.active=manager"
  export DBAPI_OPTS="$HEAP_OPTS $DBAPI_OPTS"

elif [ "$command" = "apiServer" ]; then
  exclude_jars=("spring-boot-starter-webflux" "spring-webflux" "spring-cloud-gateway-server" "spring-cloud-starter-gateway")
  generate_classpath
  add_extra_jars
  CLASS=com.gitee.freakchicken.dbapi.apiserver.OQLSUZGH
  HEAP_OPTS=$apiServer_opts
  PROFILES="-Dspring.profiles.active=apiServer"
  export DBAPI_OPTS="$HEAP_OPTS $DBAPI_OPTS"

elif [ "$command" = "gateway" ]; then
  exclude_jars=("spring-boot-starter-tomcat" "spring-boot-starter-web" "tomcat-embed-websocket" "tomcat-embed-core" "spring-webmvc")
  generate_classpath
  add_extra_jars
  CLASS=com.gitee.freakchicken.dbapi.gateway.FMtcKcgR
  HEAP_OPTS=$gateway_opts
  PROFILES="-Dspring.profiles.active=gateway -Dreactor.netty.http.server.accessLogEnabled=true "
  export DBAPI_OPTS="$HEAP_OPTS $DBAPI_OPTS"

else
  echo "Error: No command named '$command' was found."
  exit 1
fi

JAVA_COMMAND="java"
if [ ! -z "$JAVA_LOCATION" ]; then
  echo "Using Java from $JAVA_LOCATION"
  JAVA_COMMAND=$JAVA_LOCATION
fi

function stop_service() {
  if [ -f $pid ]; then
    TARGET_PID=`cat $pid`
    if kill -0 $TARGET_PID > /dev/null 2>&1; then
      echo stopping $command
      kill $TARGET_PID
      sleep $STOP_TIMEOUT
      if kill -0 $TARGET_PID > /dev/null 2>&1; then
        echo "$command did not stop gracefully after $STOP_TIMEOUT seconds: killing with kill -9"
        kill -9 $TARGET_PID
      fi
    else
      echo no $command to stop
    fi
    rm -f $pid
  else
    echo no $command to stop
  fi
}

function start_service() {
  if [ "$DOCKER" = "true" ]; then
    echo start $command in docker
    export DBAPI_OPTS="$DBAPI_OPTS -XX:-UseContainerSupport"
    exec_command="$PROFILES $DBAPI_OPTS -classpath $cp $CLASS"
    $JAVA_COMMAND $exec_command
  else
    [ -w "$DBAPI_PID_DIR" ] || mkdir -p "$DBAPI_PID_DIR"

    if [ -f $pid ]; then
      if kill -0 `cat $pid` > /dev/null 2>&1; then
        echo $command running as process `cat $pid`.  Stop it first.
        exit 1
      fi
    fi

    echo starting $command
    exec_command="$PROFILES $DBAPI_OPTS -javaagent:$service_file -classpath $cp $CLASS"
    nohup $JAVA_COMMAND $exec_command > /dev/null 2>&1 &
    echo $! > $pid
  fi
}

case $startStop in
  (start)
    start_service
    ;;

  (stop)
    stop_service
    ;;

  (status)
    # more details about the status can be added later
    serverCount=`ps -ef |grep "$CLASS" |grep -v "grep" |wc -l`
    state="STOP"
    #  font color - red
    state="[ \033[1;31m $state \033[0m ]"
    if [[ $serverCount -gt 0 ]];then
      state="RUNNING"
      # font color - green
      state="[ \033[1;32m $state \033[0m ]"
    fi
    echo -e "$command  $state"
    ;;

  (restart)
    echo restarting $command
    stop_service
    start_service
    ;;

  (*)
    echo $usage
    exit 1
    ;;

esac

echo "End $startStop $command."
