#!/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/bookkeper.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 daemon
    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
	${MVN} -f "${BK_HOME}/pom.xml" dependency:build-classpath -Dmdep.outputFile="${f}" &> /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`"

OPTS="-cp $BOOKIE_CLASSPATH $OPTS"

OPTS="$OPTS $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"}

#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
