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

set -e

BINDIR=`dirname "$0"`
BK_HOME=`cd ${BINDIR}/..;pwd`

source ${BK_HOME}/bin/common.sh

# default variables
DEFAULT_CONF=${BK_HOME}/conf/bk_server.conf
DEFAULT_ZK_CONF=${BK_HOME}/conf/zookeeper.conf

if [ -z "$BOOKIE_CONF" ]; then
  BOOKIE_CONF_TO_CHECK=${DEFAULT_CONF}
else
  BOOKIE_CONF_TO_CHECK=${BOOKIE_CONF}
fi

FIND_TABLE_SERVICE_RESULT=$(find_table_service ${BOOKIE_CONF_TO_CHECK} $1)

if [ "x${FIND_TABLE_SERVICE_RESULT}" == "xtrue" ]; then
  BOOKIE_MODULE_PATH=stream/server
  BOOKIE_MODULE_NAME=${TABLE_SERVICE_MODULE_NAME}
elif [ "x${FIND_TABLE_SERVICE_RESULT}" == "xfalse" ]; then
  BOOKIE_MODULE_PATH=bookkeeper-server
  BOOKIE_MODULE_NAME=${BOOKIE_SERVER_MODULE_NAME}
else
  echo ${FIND_TABLE_SERVICE_RESULT}
  exit 1
fi

# find the module jar
BOOKIE_JAR=$(find_module_jar ${BOOKIE_MODULE_PATH} ${BOOKIE_MODULE_NAME})

# set up the classpath
BOOKIE_CLASSPATH=$(set_module_classpath ${BOOKIE_MODULE_PATH})

bookkeeper_help() {
    cat <<EOF
Usage: bookkeeper <command>
where command is one of:

[service commands]

    bookie              Run a bookie server
    autorecovery        Run AutoRecovery service
    zookeeper           Run zookeeper server

[development commands]

    localbookie <n>     Run a test ensemble of <n> bookies locally
    standalone          Run a standalone cluster (with all service components) locally

[tooling commands]

    upgrade             Upgrade bookie filesystem
    shell               Run shell for admin commands

[other commands]

    help                This help message

or command is the full name of a class with a defined main() method.

Environment variables:
   BOOKIE_LOG_CONF        Log4j configuration file (default ${DEFAULT_LOG_CONF})
   BOOKIE_CONF            Configuration file (default: ${DEFAULT_CONF})
   BOOKIE_ZK_CONF         Configuration file for zookeeper (default: $DEFAULT_ZK_CONF)
   BOOKIE_EXTRA_OPTS      Extra options to be passed to the jvm
   BOOKIE_EXTRA_CLASSPATH Add extra paths to the bookkeeper classpath
   ENTRY_FORMATTER_CLASS  Entry formatter class to format entries.
   BOOKIE_PID_DIR         Folder where the Bookie server PID file should be stored
   BOOKIE_STOP_TIMEOUT    Wait time before forcefully kill the Bookie server instance, if the stop is not successful

These variable can also be set in conf/bkenv.sh
EOF
}

# if no args specified, show usage
if [ $# = 0 ]; then
  bookkeeper_help;
  exit 1;
fi

# get arguments
COMMAND=$1
shift

LOCALBOOKIES_CONFIG_DIR="${LOCALBOOKIES_CONFIG_DIR:-/tmp/localbookies-config}"
if [ ${COMMAND} == "shell" ]; then
  DEFAULT_LOG_CONF=${BK_HOME}/conf/log4j2.shell.xml
  if [[ $1 == "-localbookie"  ]]; then
    if [[ $2 == *:* ]];
    then
      BOOKIE_CONF=${LOCALBOOKIES_CONFIG_DIR}/$2.conf
      shift 2
    else
      BOOKIE_CONF=${LOCALBOOKIES_CONFIG_DIR}/baseconf.conf
      shift
    fi
  fi
fi

if [ -z "$BOOKIE_ZK_CONF" ]; then
    BOOKIE_ZK_CONF=$DEFAULT_ZK_CONF
fi

if [ -z "$BOOKIE_CONF" ]; then
  BOOKIE_CONF=${DEFAULT_CONF}
fi

# Configure logging
if [ -z "$BOOKIE_LOG_CONF" ]; then
  BOOKIE_LOG_CONF=${DEFAULT_LOG_CONF}
fi
BOOKIE_LOG_DIR=${BOOKIE_LOG_DIR:-"$BK_HOME/logs"}
BOOKIE_LOG_FILE=${BOOKIE_LOG_FILE:-"bookkeeper-server.log"}
BOOKIE_ROOT_LOG_LEVEL=${BOOKIE_ROOT_LOG_LEVEL:-"INFO"}
BOOKIE_ROOT_LOG_APPENDER=${BOOKIE_ROOT_LOG_APPENDER:-"CONSOLE"}

# Configure the classpath
BOOKIE_CLASSPATH="$BOOKIE_JAR:$BOOKIE_CLASSPATH:$BOOKIE_EXTRA_CLASSPATH"
BOOKIE_CLASSPATH="`dirname $BOOKIE_LOG_CONF`:$BOOKIE_CLASSPATH"

# Build the OPTS
BOOKIE_OPTS=$(build_bookie_opts)
GC_OPTS=$(build_bookie_jvm_opts ${BOOKIE_LOG_DIR} "gc_%p.log")
NETTY_OPTS=$(build_netty_opts)
LOGGING_OPTS=$(build_logging_opts ${BOOKIE_LOG_CONF} ${BOOKIE_ROOT_LOG_LEVEL} ${BOOKIE_ROOT_LOG_APPENDER} ${BOOKIE_LOG_DIR} ${BOOKIE_LOG_FILE})

BOOKIE_EXTRA_OPTS="${BOOKIE_EXTRA_OPTS} -Dorg.bouncycastle.fips.approved_only=true"
OPTS="${OPTS} -cp ${BOOKIE_CLASSPATH} ${BOOKIE_OPTS} ${GC_OPTS} ${NETTY_OPTS} ${LOGGING_OPTS} ${BOOKIE_EXTRA_OPTS}"

# Create log dir if it doesn't exist
if [ ! -d ${BOOKIE_LOG_DIR} ]; then
    mkdir ${BOOKIE_LOG_DIR}
fi

#Change to BK_HOME to support relative paths
cd "$BK_HOME"
if [ ${COMMAND} == "bookie" ]; then
  exec "${JAVA}" ${OPTS} ${JMX_ARGS} org.apache.bookkeeper.server.Main --conf ${BOOKIE_CONF} $@
elif [ ${COMMAND} == "autorecovery" ]; then
  exec "${JAVA}" ${OPTS} ${JMX_ARGS} org.apache.bookkeeper.replication.AutoRecoveryMain --conf ${BOOKIE_CONF} $@
elif [ ${COMMAND} == "localbookie" ]; then
  NUMBER=$1
  shift
  exec "${JAVA}" ${OPTS} ${JMX_ARGS} -Dzookeeper.4lw.commands.whitelist='*' org.apache.bookkeeper.util.LocalBookKeeper ${NUMBER} ${BOOKIE_CONF} $@
elif [ ${COMMAND} == "standalone" ]; then
  exec "${JAVA}" ${OPTS} ${JMX_ARGS} -Dzookeeper.4lw.commands.whitelist='*' org.apache.bookkeeper.stream.cluster.StandaloneStarter --conf ${BK_HOME}/conf/standalone.conf $@
elif [ ${COMMAND} == "upgrade" ]; then
  exec "${JAVA}" ${OPTS} org.apache.bookkeeper.bookie.FileSystemUpgrade --conf ${BOOKIE_CONF} $@
elif [ $COMMAND == "zookeeper" ]; then
    BOOKIE_LOG_FILE=${BOOKIE_LOG_FILE:-"zookeeper.log"}
    exec "${JAVA}" $OPTS -Dbookkeeper.log.file=$BOOKIE_LOG_FILE org.apache.zookeeper.server.quorum.QuorumPeerMain $BOOKIE_ZK_CONF $@
elif [ ${COMMAND} == "shell" ]; then
  ENTRY_FORMATTER_ARG="-DentryFormatterClass=${ENTRY_FORMATTER_CLASS:-org.apache.bookkeeper.util.StringEntryFormatter}"
  exec "${JAVA}" ${OPTS} ${ENTRY_FORMATTER_ARG} org.apache.bookkeeper.bookie.BookieShell -conf ${BOOKIE_CONF} $@
elif [ ${COMMAND} == "help" ]; then
  bookkeeper_help;
else
  exec "${JAVA}" ${OPTS} ${COMMAND} $@
fi

