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

# check if net.ipv6.bindv6only is set to 1
bindv6only=$(/sbin/sysctl -n net.ipv6.bindv6only 2> /dev/null)
if [ -n "$bindv6only" ] && [ "$bindv6only" -eq "1" ]
then
  echo "Error: \"net.ipv6.bindv6only\" is set to 1 - Java networking could be broken"
  echo "For more info (the following page also applies to bookkeeper): http://wiki.apache.org/hadoop/HadoopIPv6"
  exit 1
fi

# See the following page for extensive details on setting
# up the JVM to accept JMX remote management:
# http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html
# by default we allow local JMX connections
if [ "x$JMXLOCALONLY" = "x" ]
then
    JMXLOCALONLY=false
fi

if [ "x$JMXDISABLE" = "x" ]
then
    # for some reason these two options are necessary on jdk6 on Ubuntu
    #   accord to the docs they are not necessary, but otw jconsole cannot
    #   do a local attach
    JMX_ARGS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=$JMXLOCALONLY"
else
    echo "JMX disabled by user request" >&2
fi

BINDIR=`dirname "$0"`
BK_HOME=`cd -P $BINDIR/..;pwd`

DEFAULT_CONF=$BK_HOME/conf/bookkeeper.conf
DEFAULT_LOG_CONF=$BK_HOME/conf/log4j2.yaml

source $BK_HOME/conf/bkenv.sh

# Check for the java to use
if [[ -z $JAVA_HOME ]]; then
    JAVA=$(which java)
    if [ $? = 0 ]; then
        echo "JAVA_HOME not set, using java from PATH. ($JAVA)"
    else
        echo "Error: JAVA_HOME not set, and no java executable found in $PATH." 1>&2
        exit 1
    fi
else
    JAVA=$JAVA_HOME/bin/java
fi

# exclude tests jar
RELEASE_JAR=`ls $BK_HOME/bookkeeper-server-*.jar 2> /dev/null | grep -v tests | tail -1`
if [ $? == 0 ]; then
    BOOKIE_JAR=$RELEASE_JAR
fi

# exclude tests jar
BUILT_JAR=`ls $BK_HOME/target/bookkeeper-server-*.jar 2> /dev/null | grep -v tests | tail -1`
if [ $? != 0 ] && [ ! -e "$BOOKIE_JAR" ]; then
    echo "\nCouldn't find bookkeeper jar.";
    echo "Make sure you've run 'mvn package'\n";
    exit 1;
elif [ -e "$BUILT_JAR" ]; then
    BOOKIE_JAR=$BUILT_JAR
fi

bookkeeper_help() {
    cat <<EOF
Usage: bookkeeper <command>
where command is one of:
    bookie              Run a bookie server
    autorecovery        Run AutoRecovery service
    localbookie <n>     Run a test ensemble of <n> bookies locally
    upgrade             Upgrade bookie filesystem
    shell               Run shell for admin 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_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
}

add_maven_deps_to_classpath() {
    MVN="mvn"
    if [ "$MAVEN_HOME" != "" ]; then
	MVN=${MAVEN_HOME}/bin/mvn
    fi

    # Need to generate classpath from maven pom. This is costly so generate it
    # and cache it. Save the file into our target dir so a mvn clean will get
    # clean it up and force us create a new one.
    f="${BK_HOME}/distribution/server/target/classpath.txt"
    if [ ! -f "${f}" ]
    then
    (
      cd "${BK_HOME}"
      ${MVN} -pl distribution/server generate-sources &> /dev/null
    )
    fi
    BOOKIE_CLASSPATH=${CLASSPATH}:`cat "${f}"`
}

if [ -d "$BK_HOME/lib" ]; then
    for i in $BK_HOME/lib/*.jar; do
	BOOKIE_CLASSPATH=$BOOKIE_CLASSPATH:$i
    done
else
    add_maven_deps_to_classpath
fi

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

# get arguments
COMMAND=$1
shift

if [ $COMMAND == "shell" ]; then
    DEFAULT_LOG_CONF=$BK_HOME/conf/log4j2.yaml
fi

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

if [ -z "$BOOKIE_LOG_CONF" ]; then
    BOOKIE_LOG_CONF=$DEFAULT_LOG_CONF
fi

BOOKIE_CLASSPATH="$BOOKIE_JAR:$BOOKIE_CLASSPATH:$BOOKIE_EXTRA_CLASSPATH"
BOOKIE_CLASSPATH="`dirname $BOOKIE_LOG_CONF`:$BOOKIE_CLASSPATH"
OPTS="$OPTS -Dlog4j.configurationFile=`basename $BOOKIE_LOG_CONF`"

# Allow Netty to use reflection access
OPTS="$OPTS -Dio.netty.tryReflectionSetAccessible=true"

OPTS="-cp $BOOKIE_CLASSPATH $OPTS"

OPTS="$OPTS $BOOKIE_MEM $BOOKIE_GC $BOOKIE_GC_LOG $BOOKIE_EXTRA_OPTS"

# Disable ipv6 as it can cause issues
OPTS="$OPTS -Djava.net.preferIPv4Stack=true"

# log directory & file
BOOKIE_LOG_APPENDER=${BOOKIE_LOG_APPENDER:-"Console"}

# send bookie shell output to console unconditionally
if [ $COMMAND == "shell" ]; then
BOOKIE_LOG_APPENDER=Console
fi

BOOKIE_LOG_DIR=${BOOKIE_LOG_DIR:-"$BK_HOME/logs"}
BOOKIE_LOG_FILE=${BOOKIE_LOG_FILE:-"bookkeeper-server.log"}
if [ ! -d "$BOOKIE_LOG_DIR" ]; then
  mkdir -p "$BOOKIE_LOG_DIR"
fi

#Configure log configuration system properties
OPTS="$OPTS -Dpulsar.log.appender=$BOOKIE_LOG_APPENDER"
OPTS="$OPTS -Dbk.log.appender=$BOOKIE_LOG_APPENDER"
OPTS="$OPTS -Dbk.log.level=error"
OPTS="$OPTS -Dpulsar.log.dir=$BOOKIE_LOG_DIR"
OPTS="$OPTS -Dpulsar.log.file=$BOOKIE_LOG_FILE"

#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 org.apache.bookkeeper.util.LocalBookKeeper $NUMBER $BOOKIE_CONF $@
elif [ $COMMAND == "upgrade" ]; then
    exec $JAVA $OPTS org.apache.bookkeeper.bookie.FileSystemUpgrade --conf $BOOKIE_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" -o $COMMAND == "--help" -o $COMMAND == "-h" ]; then
    bookkeeper_help;
else
    exec $JAVA $OPTS $COMMAND $@
fi
