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

warn() {
    echo "${PROGNAME}: $*"
}

die() {
    warn "$*"
    exit 1
}

detectOS() {
    # OS specific support (must be 'true' or 'false').
    cygwin=false;
    mingw=false;
    darwin=false;
    aix=false;
    os400=false;
    hpux=false;
    solaris=false;
    case "`uname`" in
        CYGWIN*)
            cygwin=true
            ;;
        MINGW*)
            mingw=true
            ;;
        Darwin*)
            darwin=true
            ;;
        AIX*)
            aix=true
            # For AIX, set an environment variable
            export LDR_CNTRL=MAXDATA=0xB0000000@DSA
            ;;
        OS400*)
            os400=true
            ;;
        HP-UX*)
            hpux=true
            # For HP-UX, set an environment variable
            export PS_PREFIX="UNIX95= "
            ;;
        SunOS*)
            solaris=true
            ;;
    esac
}

unlimitFD() {
    # Use the maximum available, or set MAX_FD != -1 to use that
    if [ "x${MAX_FD}" = "x" ]; then
        MAX_FD="maximum"
    fi

    # Increase the maximum file descriptors if we can
    if [ "x`command -v ulimit`" != "x" ] && [ "${os400}" = "false" ] ; then
        if [ "${MAX_FD}" = "maximum" ] || [ "${MAX_FD}" = "max" ]; then
            MAX_FD_LIMIT=`ulimit -H -n`
            if [ $? -eq 0 ]; then
                # use the system max
                MAX_FD="${MAX_FD_LIMIT}"
            else
                warn "Could not query system maximum file descriptor limit: ${MAX_FD_LIMIT}"
            fi
        fi
        if [ "${MAX_FD}" != 'unlimited' ]; then
            ulimit -n "${MAX_FD}" > /dev/null
            if [ $? -ne 0 ]; then
                warn "Could not set maximum file descriptor limit: ${MAX_FD}"
            fi
        fi
     fi
}

locateHome() {
    if [ "x${KARAF_HOME}" != "x" ]; then
        warn "Ignoring predefined value for KARAF_HOME"
        unset KARAF_HOME
    fi
    if [ "x${KARAF_HOME}" = "x" ]; then
        # In POSIX shells, CDPATH may cause cd to write to stdout
        (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
        # KARAF_HOME is not provided, fall back to default
        KARAF_HOME=`cd "${DIRNAME}/.." || exit 2; pwd`
    fi

    if [ ! -d "${KARAF_HOME}" ]; then
        die "KARAF_HOME is not valid: ${KARAF_HOME}"
    fi
}

locateBase() {
    if [ "x${KARAF_BASE}" != "x" ]; then
        if [ ! -d "${KARAF_BASE}" ]; then
            die "KARAF_BASE is not valid: ${KARAF_BASE}"
        fi
    else
        KARAF_BASE=${KARAF_HOME}
    fi
}

locateData() {
    if [ "x${KARAF_DATA}" != "x" ]; then
        if [ ! -d "${KARAF_DATA}" ]; then
            die "KARAF_DATA is not valid: ${KARAF_DATA}"
        fi
    else
        KARAF_DATA=${KARAF_BASE}/data
    fi
}

locateEtc() {
    if [ "x${KARAF_ETC}" != "x" ]; then
        if [ ! -d "${KARAF_ETC}" ]; then
            die "KARAF_ETC is not valid: ${KARAF_ETC}"
        fi
    else
        KARAF_ETC=${KARAF_BASE}/etc
    fi
}

locateLog() {
    if [ "x${KARAF_LOG}" != "x" ]; then
        if [ ! -d "${KARAF_LOG}" ]; then
            die "KARAF_LOG is not valid: ${KARAF_LOG}"
        fi
    else
        KARAF_LOG=${KARAF_DATA}/log
    fi
}

setupNativePath() {
    # Support for loading native libraries
    if [ "x${LD_LIBRARY_PATH}" != "x" ]; then
        LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${KARAF_BASE}/lib:${KARAF_HOME}/lib"
    else
        LD_LIBRARY_PATH="${KARAF_BASE}/lib:${KARAF_HOME}/lib"
    fi

    # For Cygwin, set PATH from LD_LIBRARY_PATH
    if ${cygwin}; then
        LD_LIBRARY_PATH=`cygpath --path --windows "${LD_LIBRARY_PATH}"`
        PATH="${PATH};${LD_LIBRARY_PATH}"
        export PATH
    fi
    export LD_LIBRARY_PATH
}

pathCanonical() {
    dst="${1}"
    while [ -h "${dst}" ] ; do
        ls=`ls -ld "${dst}"`
        link=`expr "${ls}" : '.*-> \(.*\)$'`
        if expr "${link}" : '/.*' > /dev/null; then
            dst="${link}"
        else
            dst="`dirname "${dst}"`/${link}"
        fi
    done
    bas=`basename "${dst}"`
    dir=`dirname "${dst}"`
    if [ "${bas}" != "${dir}" ]; then
        dst="`pathCanonical "${dir}"`/${bas}"
    fi
    echo "${dst}" | sed -e 's#//#/#g' -e 's#/./#/#g' -e 's#/[^/]*/../#/#g'
}

locateJava() {
    # Setup the Java Virtual Machine
    if ${cygwin} ; then
        [ -n "${JAVA}" ] && JAVA=`cygpath --unix "${JAVA}"`
        [ -n "${JAVA_HOME}" ] && JAVA_HOME=`cygpath --unix "${JAVA_HOME}"`
    fi

    if [ "x${JAVA_HOME}" = "x" ] && [ "${darwin}" = "true" ]; then
        JAVA_HOME="`/usr/libexec/java_home -v 1.8`"
    fi
    if [ "x${JAVA_HOME}" = "x" ] && [ -r /etc/gentoo-release ] ; then
        JAVA_HOME=`java-config --jre-home`
    fi
    if [ "x${JAVA}" = "x" ]; then
        if [ "x${JAVA_HOME}" != "x" ]; then
            if [ ! -d "${JAVA_HOME}" ]; then
                die "JAVA_HOME is not valid: ${JAVA_HOME}"
            fi
            JAVA="${JAVA_HOME}/bin/java"
        else
            warn "JAVA_HOME not set; results may vary"
            JAVA=`command -v java`
            if [ "x${JAVA}" = "x" ]; then
                die "java command not found"
            fi
        fi
    fi
    if [ "x${JAVA_HOME}" = "x" ]; then
        JAVA_BIN=`pathCanonical "${JAVA}"`
        JAVA_BIN_DIR=`dirname "${JAVA_BIN}"`
        JAVA_HOME="`dirname "${JAVA_BIN_DIR}"`"
    fi
}

detectJVM() {
    # This service should call $(java -version),
    # read stdout, and look for hints
    if "${JAVA}" -version 2>&1 | grep "^IBM" ; then
        JVM_VENDOR="IBM"
    # on OS/400, java -version does not contain IBM explicitly
    elif ${os400}; then
        JVM_VENDOR="IBM"
    else
        JVM_VENDOR="SUN"
    fi
    # echo "JVM vendor is ${JVM_VENDOR}"
}

checkJvmVersion() {
    # Use in priority xpg4 awk or nawk on SunOS as standard awk is outdated
    AWK=awk
    if ${solaris}; then
        if [ -x /usr/xpg4/bin/awk ]; then
            AWK=/usr/xpg4/bin/awk
        elif [ -x /usr/bin/nawk ]; then
            AWK=/usr/bin/nawk
        fi
    fi

    VERSION=`"${JAVA}" -version 2>&1 | ${AWK} -F '"' '/version/ {print $2}' | sed -e 's/_.*//g; s/^1\.//g; s/\..*//g; s/-.*//g;s/-.*//g; s/^[A-Za-z].*//'`

    # java must be at least version 8
    if [ "${VERSION}" -lt "8" ]; then
        die "JVM must be version 1.8 or greater"
    fi
}

setupDebugOptions() {

    # Set Debug options if enabled
    if [ "x${KARAF_DEBUG}" != "x" ]; then
        # Use the defaults if JAVA_DEBUG_OPTS was not set
        if [ "x${JAVA_DEBUG_OPTS}" = "x" ]; then
            JAVA_DEBUG_OPTS="${DEFAULT_JAVA_DEBUG_OPTS}"
        fi

        JAVA_OPTS="${JAVA_DEBUG_OPTS} ${JAVA_OPTS}"
        warn "Enabling Java debug options: ${JAVA_DEBUG_OPTS}"
    fi
}

setupVendorSepcifics() {
    #Set the JVM_VENDOR specific JVM flags
    if [ "${JVM_VENDOR}" = "SUN" ]; then
        #JAVA_VENDOR_OPTS="-Dcom.sun.management.jmxremote"
        JAVA_VENDOR_OPTS=""
    elif [ "${JVM_VENDOR}" = "IBM" ]; then
        if ${os400}; then
            JAVA_VENDOR_OPTS=
        elif ${aix}; then
            JAVA_VENDOR_OPTS="-Xverify:none -Xdump:heap -Xlp "
        else
            JAVA_VENDOR_OPTS="-Xverify:none"
        fi
    fi
}

setupDefaults() {
    DEFAULT_JAVA_OPTS="-XX:+UnlockDiagnosticVMOptions "

    if [ "${VERSION}" -gt "11" ]; then
      # TODO revisit EventAdminImpl to avoid use of Subject.getSubject(AccessController.getContext());
      # -Djava.security.manager=allow is a workaround for SecurityController deprecation in JDK23+
      DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS -Djava.security.manager=allow "
    fi

    setupVendorSepcifics

    DEFAULT_JAVA_OPTS="${DEFAULT_JAVA_OPTS} ${JAVA_VENDOR_OPTS}"

    DEFAULT_JAVA_DEBUG_PORT="5005"
    if [ "x${JAVA_DEBUG_PORT}" = "x" ]; then
        JAVA_DEBUG_PORT="${DEFAULT_JAVA_DEBUG_PORT}"
    fi
    DEFAULT_JAVA_DEBUG_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:${JAVA_DEBUG_PORT}"
    DEFAULT_JAVA_DEBUGS_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:${JAVA_DEBUG_PORT}"

    if [ "x${JAVA_OPTS}" = "x" ]; then
        JAVA_OPTS="${DEFAULT_JAVA_OPTS}"
    fi

    if [ "x${EXTRA_JAVA_OPTS}" != "x" ]; then
        JAVA_OPTS="${JAVA_OPTS} ${EXTRA_JAVA_OPTS}"
    fi
    export JAVA_OPTS


    ##
    ## TODO: Move to conf/profiler/yourkit.{sh|cmd}
    ##
    # Uncomment to enable YourKit profiling
    #DEFAULT_JAVA_DEBUG_OPTS="-Xrunyjpagent"
}

convertPaths() {
    if $cygwin; then
        if [ ! -z "${KARAF_HOME}" ]; then
            KARAF_HOME=`cygpath --path --windows "${KARAF_HOME}"`
        fi
        if [ ! -z "${KARAF_BASE}" ]; then
            KARAF_BASE=`cygpath --path --windows "${KARAF_BASE}"`
        fi
        if [ ! -z "${KARAF_DATA}" ]; then
            KARAF_DATA=`cygpath --path --windows "${KARAF_DATA}"`
        fi
        if [ ! -z "${KARAF_ETC}" ]; then
            KARAF_ETC=`cygpath --path --windows "${KARAF_ETC}"`
        fi
        if [ ! -z "${CLASSPATH}" ]; then
            CLASSPATH=`cygpath --path --windows "${CLASSPATH}"`
        fi
    fi
}
