#!/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 net.ipv6.bindv6only
if [ -f /sbin/sysctl ] && [ -f /proc/sys/net/ipv6/bindv6only ]; then
  # 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
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

# 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

BINDIR=${BK_BINDIR:-"`dirname "$0"`"}
BK_HOME=${BK_HOME:-"`cd ${BINDIR}/..;pwd`"}
BK_CONFDIR=${BK_HOME}/conf
DEFAULT_LOG_CONF=${BK_CONFDIR}/log4j.properties

source ${BK_CONFDIR}/nettyenv.sh
source ${BK_CONFDIR}/bkenv.sh
source ${BK_CONFDIR}/bk_cli_env.sh

detect_jdk8() {

  if [ -f "$JAVA_HOME/bin/jshell" ]; then
     echo "0"
  else
     echo "1"
  fi
  return
}

# default netty settings
NETTY_LEAK_DETECTION_LEVEL=${NETTY_LEAK_DETECTION_LEVEL:-"disabled"}
NETTY_RECYCLER_MAXCAPACITY=${NETTY_RECYCLER_MAXCAPACITY:-"1000"}
NETTY_RECYCLER_LINKCAPACITY=${NETTY_RECYCLER_LINKCAPACITY:-"1024"}

USING_JDK8=$(detect_jdk8)

if [ "$USING_JDK8" -ne "1" ]; then
   DEFAULT_BOOKIE_GC_OPTS="-XX:+UseG1GC \
    -XX:MaxGCPauseMillis=10 \
    -XX:+ParallelRefProcEnabled \
    -XX:+DisableExplicitGC"
   DEFAULT_BOOKIE_GC_LOGGING_OPTS=""
else
  DEFAULT_BOOKIE_GC_OPTS="-XX:+UseG1GC \
    -XX:MaxGCPauseMillis=10 \
    -XX:+ParallelRefProcEnabled \
    -XX:+UnlockExperimentalVMOptions \
    -XX:+AggressiveOpts \
    -XX:+DoEscapeAnalysis \
    -XX:ParallelGCThreads=32 \
    -XX:ConcGCThreads=32 \
    -XX:G1NewSizePercent=50 \
    -XX:+DisableExplicitGC \
    -XX:-ResizePLAB"
  DEFAULT_BOOKIE_GC_LOGGING_OPTS="-XX:+PrintGCDetails \
    -XX:+PrintGCApplicationStoppedTime  \
    -XX:+UseGCLogFileRotation \
    -XX:NumberOfGCLogFiles=5 \
    -XX:GCLogFileSize=64m"
fi

BOOKIE_MAX_HEAP_MEMORY=${BOOKIE_MAX_HEAP_MEMORY:-"1g"}
BOOKIE_MIN_HEAP_MEMORY=${BOOKIE_MIN_HEAP_MEMORY:-"1g"}
BOOKIE_MAX_DIRECT_MEMORY=${BOOKIE_MAX_DIRECT_MEMORY:-"2g"}
BOOKIE_MEM_OPTS=${BOOKIE_MEM_OPTS:-"-Xms${BOOKIE_MIN_HEAP_MEMORY} -Xmx${BOOKIE_MAX_HEAP_MEMORY} -XX:MaxDirectMemorySize=${BOOKIE_MAX_DIRECT_MEMORY}"}
BOOKIE_GC_OPTS=${BOOKIE_GC_OPTS:-"${DEFAULT_BOOKIE_GC_OPTS}"}
BOOKIE_GC_LOGGING_OPTS=${BOOKIE_GC_LOGGING_OPTS:-"${DEFAULT_BOOKIE_GC_LOGGING_OPTS}"}

# default CLI JVM settings
DEFAULT_CLI_GC_OPTS="-XX:+UseG1GC \
    -XX:MaxGCPauseMillis=10"
if [ "$USING_JDK8" -ne "1" ]; then
  DEFAULT_CLI_GC_LOGGING_OPTS=""
else
  DEFAULT_CLI_GC_LOGGING_OPTS="-XX:+PrintGCDetails \
    -XX:+PrintGCApplicationStoppedTime  \
    -XX:+UseGCLogFileRotation \
    -XX:NumberOfGCLogFiles=5 \
    -XX:GCLogFileSize=64m"
fi

CLI_MAX_HEAP_MEMORY=${CLI_MAX_HEAP_MEMORY:-"512M"}
CLI_MIN_HEAP_MEMORY=${CLI_MIN_HEAP_MEMORY:-"256M"}
CLI_MEM_OPTS=${CLI_MEM_OPTS:-"-Xms${CLI_MIN_HEAP_MEMORY} -Xmx${CLI_MAX_HEAP_MEMORY}"}
CLI_GC_OPTS=${CLI_GC_OPTS:-"${DEFAULT_CLI_GC_OPTS}"}
CLI_GC_LOGGING_OPTS=${CLI_GC_LOGGING_OPTS:-"${DEFAULT_CLI_GC_LOGGING_OPTS}"}

# module names
BOOKIE_SERVER_MODULE_NAME="(org.apache.bookkeeper-)?bookkeeper-server"
TABLE_SERVICE_MODULE_NAME="(org.apache.bookkeeper-)?stream-storage-server"

is_released_binary() {
  if [ -d ${BK_HOME}/lib ]; then
    echo "true"
    return
  else
    echo "false"
    return
  fi
}

find_module_jar_at() {
  DIR=$1
  MODULE=$2
  REGEX="^${MODULE}-[0-9\\.]*((-[a-zA-Z]*(-[0-9]*)?)|(-SNAPSHOT))?.jar$"
  if [ -d ${DIR} ]; then
    cd ${DIR}
    for f in *.jar; do
      if [[ ${f} =~ ${REGEX} ]]; then
        echo ${DIR}/${f}
        return
      fi
    done
  fi
}

find_module_release_jar() {
  MODULE_NAME=$1
  RELEASE_JAR=$(find_module_jar_at ${BK_HOME} ${MODULE_NAME})
  if [ -n "${RELEASE_JAR}" ]; then
    MODULE_JAR=${RELEASE_JAR}
  else
    RELEASE_JAR=$(find_module_jar_at ${BK_HOME}/lib ${MODULE_NAME})
    if [ -n "${RELEASE_JAR}" ]; then
      MODULE_JAR=${RELEASE_JAR}
    fi
  fi
  echo ${RELEASE_JAR}
  return
}

find_module_jar() {
  MODULE_PATH=$1
  MODULE_NAME=$2
  RELEASE_JAR=$(find_module_jar_at ${BK_HOME} ${MODULE_NAME})
  if [ -n "${RELEASE_JAR}" ]; then
    MODULE_JAR=${RELEASE_JAR}
  else
    RELEASE_JAR=$(find_module_jar_at ${BK_HOME}/lib ${MODULE_NAME})
    if [ -n "${RELEASE_JAR}" ]; then
      MODULE_JAR=${RELEASE_JAR}
    fi
  fi

  if [ -z "${MODULE_JAR}" ]; then
    BUILT_JAR=$(find_module_jar_at ${BK_HOME}/${MODULE_PATH}/target ${MODULE_NAME})
    if [ -z "${BUILT_JAR}" ]; then
      echo "Couldn't find module '${MODULE_NAME}' jar." >&2
      read -p "Do you want me to run \`mvn package -DskipTests -Dtwitter -Dstream\` for you ? (y|n) " answer
      case "${answer:0:1}" in
        y|Y )
          mkdir -p ${BK_HOME}/logs
          output="${BK_HOME}/logs/build.out"
          echo "see output at ${output} for the progress ..." >&2
          mvn package -DskipTests -Dtwitter -Dstream &> ${output} 
          ;;
        * )
          exit 1
          ;;
      esac

      BUILT_JAR=$(find_module_jar_at ${BK_HOME}/${MODULE_PATH}/target ${MODULE_NAME})
    fi
    if [ -n "${BUILT_JAR}" ]; then
      MODULE_JAR=${BUILT_JAR}
    fi
  fi

  if [ ! -e "${MODULE_JAR}" ]; then
    echo "Could not find module '${MODULE_JAR}' jar." >&2
    exit 1
  fi
  echo ${MODULE_JAR}
  return
}

add_maven_deps_to_classpath() {
  MODULE_PATH=$1
  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}/${MODULE_PATH}/target/cached_classpath.txt"
  output="${BK_HOME}/${MODULE_PATH}/target/build_classpath.out"
  if [ ! -f ${f} ]; then
    echo "the classpath of module '${MODULE_PATH}' is not found, generating it ..." >&2
    echo "see output at ${output} for the progress ..." >&2
    ${MVN} -f "${BK_HOME}/${MODULE_PATH}/pom.xml" -Dtwitter -Dstream dependency:build-classpath -Dmdep.outputFile="target/cached_classpath.txt" &> ${output}
    echo "the classpath of module '${MODULE_PATH}' is generated at '${f}'." >&2
  fi
}

set_module_classpath() {
  MODULE_PATH=$1
  if [ -d "${BK_HOME}/lib" ]; then
    BK_CLASSPATH=""
    for i in ${BK_HOME}/lib/*.jar; do
      BK_CLASSPATH=${BK_CLASSPATH}:${i}
    done
    echo ${BK_CLASSPATH}
  else
    add_maven_deps_to_classpath ${MODULE_PATH} >&2
    cat ${BK_HOME}/${MODULE_PATH}/target/cached_classpath.txt
  fi
  return
}

build_bookie_jvm_opts() {
  LOG_DIR=$1
  GC_LOG_FILENAME=$2
  if [ "$USING_JDK8" -eq "1" ]; then
    echo "$BOOKIE_MEM_OPTS $BOOKIE_GC_OPTS $BOOKIE_GC_LOGGING_OPTS $BOOKIE_PERF_OPTS -Xloggc:${LOG_DIR}/${GC_LOG_FILENAME}"
  else
    echo "$BOOKIE_MEM_OPTS $BOOKIE_GC_OPTS $BOOKIE_GC_LOGGING_OPTS $BOOKIE_PERF_OPTS -Xlog:gc=info:file=${LOG_DIR}/${GC_LOG_FILENAME}::filecount=5,filesize=64m"
  fi
  return
}

build_cli_jvm_opts() {
  LOG_DIR=$1
  GC_LOG_FILENAME=$2
  if [ "$USING_JDK8" -eq "1" ]; then
    echo "$CLI_MEM_OPTS $CLI_GC_OPTS $CLI_GC_LOGGING_OPTS -Xloggc:${LOG_DIR}/${GC_LOG_FILENAME}"
  else
    echo "$CLI_MEM_OPTS $CLI_GC_OPTS $CLI_GC_LOGGING_OPTS -Xlog:gc=info:file=${LOG_DIR}/${GC_LOG_FILENAME}::filecount=5,filesize=64m"
  fi
  return
}

build_netty_opts() {
  echo "-Dio.netty.leakDetectionLevel=${NETTY_LEAK_DETECTION_LEVEL} \
    -Dio.netty.recycler.maxCapacity.default=${NETTY_RECYCLER_MAXCAPACITY} \
    -Dio.netty.recycler.linkCapacity=${NETTY_RECYCLER_LINKCAPACITY}"
}

build_logging_opts() {
  CONF_FILE=$1
  LOG_DIR=$2
  LOG_FILE=$3
  LOGGER=$4

  echo "-Dlog4j.configuration=`basename ${CONF_FILE}` \
    -Dbookkeeper.root.logger=${LOGGER} \
    -Dbookkeeper.log.dir=${LOG_DIR} \
    -Dbookkeeper.log.file=${LOG_FILE}"
}

build_cli_logging_opts() {
  CONF_FILE=$1
  LOG_DIR=$2
  LOG_FILE=$3
  LOGGER=$4

  echo "-Dlog4j.configuration=`basename ${CONF_FILE}` \
    -Dbookkeeper.cli.root.logger=${LOGGER} \
    -Dbookkeeper.cli.log.dir=${LOG_DIR} \
    -Dbookkeeper.cli.log.file=${LOG_FILE}"
}

build_bookie_opts() {
  echo "-Djava.net.preferIPv4Stack=true"
}

find_table_service() {
  BOOKIE_CONF_TO_CHECK=$1
  SERVICE_COMMAND=$2

  # check if it is a released binary
  IS_RELEASED_BINARY=$(is_released_binary)

  # check if table service is released
  TABLE_SERVICE_RELEASED="true"
  if [ "x${IS_RELEASED_BINARY}" == "xtrue" ]; then
    TABLE_SERVICE_RELEASE_JAR=$(find_module_release_jar ${TABLE_SERVICE_MODULE_NAME})
    if [ "x${TABLE_SERVICE_RELEASE_JAR}" == "x" ]; then
      TABLE_SERVICE_RELEASED="false"
    fi
  fi
  
  # check the configuration to see if table service is enabled or not.
  if [ -z "${ENABLE_TABLE_SERVICE}" ]; then
    # mask exit code if the configuration file doesn't contain `StreamStorageLifecycleComponent`
    TABLE_SERVICE_SETTING=$(grep StreamStorageLifecycleComponent ${BOOKIE_CONF_TO_CHECK} | cat)
    if [[ "${TABLE_SERVICE_SETTING}" =~ ^extraServerComponents.* ]]; then
      if [ "x${TABLE_SERVICE_RELEASED}" == "xfalse" ]; then
        echo "The release binary is built without table service. Please disable \`StreamStorageLifecycleComponent\` in your bookie configuration at '${BOOKIE_CONF_TO_CHECK}'."
        return
      fi
      ENABLE_TABLE_SERVICE="true"
    fi
  fi
  
  # standalone only run
  if [ \( "x${SERVICE_COMMAND}" == "xstandalone" \) -a \( "x${TABLE_SERVICE_RELEASED}" == "xfalse" \) ]; then
    echo "The release binary is built without table service. Use \`localbookie <n>\` instead of \`standalone\` for local development."
    return
  fi

  if [ \( "x${SERVICE_COMMAND}" == "xstandalone" \) -o \( "x${ENABLE_TABLE_SERVICE}" == "xtrue" \) ]; then
    echo "true"
    return
  else
    echo "false"
    return
  fi
}
