#!/bin/sh
#
#  Supported environment variables:
#
#  DEBUG: 'true' to provide logging output
#
#  SECURITY_DEBUG: 'true' to provide security-related debugging
#      output.
#
#  SRM_CONFIG: location of a configuration file that is used as
#      default values.  Empty string or 'NONE' disables this feature.
#
#  JAVA_HOME: location of the JDK.  Overrides the java executable
#      found used PATH.  The executable $JAVA_HOME/bin/java must
#      exist.
#
#  SRM_JAVA_OPTIONS: options used when creating the JVM.
#

choosejava() {
    local testjava bestversion=0 version

    if [ -n "$JAVA_HOME" ]; then
        [ -x "$JAVA_HOME/bin/java" ] || fail "Missing executable at \$JAVA_HOME/bin/java"
        java="$JAVA_HOME/bin/java"
    elif which java >/dev/null 2>&1; then
        java=java
    else
        for i in /usr /usr/local /usr/java /usr/local/java /opt /opt/java; do
            for j in $i/*sdk* $i/*jdk* $i/*java* $i/*jre* $i; do
                if [ -x $j/bin/java ] ; then
                    testjava=$1/bin/java
                    # FIXME: extracting the version string is broken
                    # for OpenJDK, with which 'java -version' yields a
                    # line like:
                    #
                    #     openjdk version 1.8.0_131
                    version=$($testjava -version 2>&1 >/dev/null | tr -d '"' | awk '/java version/{print $3}')

                    # FIXME: versions are multi-element, with '.' and
                    # '_' as seperators.
                    if $bestversion -lt $version; then
                        bestversion=$version
                        java=$testjava
                    fi
                fi
            done
        done
    fi

    [ -n "$java" ]
}

java() {
    cmd="$java $@"
    if [ "$DEBUG" = "true" ]; then
        echo "$cmd"
    fi
    CLASSPATH="$SRM_PATH/lib/*" sh -c "$cmd"
}

runSRM() {
    java $java_options gov.fnal.srm.util.SRMDispatcher $srm_options $enforced_srm_options "$@"
}

fail() {
    for msg in "$@"; do
        echo "$msg" >&2
    done
    exit 1
}

[ -n "$SRM_PATH" ] || fail "SRM_PATH is not set"

if [ "$SRM_CONFIG" = "NONE" ]; then
    unset SRM_CONFIG
fi

if [ -z "$SRM_JAVA_OPTIONS" ]; then
    SRM_JAVA_OPTIONS="-XX:+TieredCompilation -XX:TieredStopAtLevel=1"
fi


choosejava || fail "Unable to find the 'java' program.  Make sure it is installed" \
                   "and define the JAVA_HOME environment variable, if necessary"

java_options="$SRM_JAVA_OPTIONS -Djava.protocol.handler.pkgs=org.globus.net.protocol"

if [ "$DEBUG" = "true" ]; then
    logback="logback-axis.xml"
    java_options="$java_options -Delectric.logging=SOAP,HTTP"
elif [ "$SECURITY_DEBUG" = "true" ]; then
    logback="logback-security.xml"
else
    logback="logback.xml"
fi
java_options="$java_options \"-Dlogback.configurationFile=$SRM_PATH/conf/$logback\""

if [ -n "$X509_USER_PROXY" ]; then
    enforced_srm_options="-use_proxy=true \"-x509_user_proxy=$X509_USER_PROXY\""
elif [ -r /tmp/x509up_u$(id -u) ]; then
    srm_options="-use_proxy=true -x509_user_proxy=/tmp/x509up_u$(id -u)"
else
    srm_options="-use_proxy=false \"-x509_user_cert=$HOME/.globus/usercert.pem\" \"-x509_user_key=$HOME/.globus/userkey.pem\""
fi

if [ -n "$X509_CERT_DIR" ]; then
    enforced_srm_options="$enforced_srm_options \"-x509_user_trusted_certificates=$X509_CERT_DIR\""
elif [ -d "$HOME/.globus/certificates" ]; then
    srm_options="$srm_options \"-x509_user_trusted_certificates=$HOME/.globus/certificates\""
else
    srm_options="$srm_options -x509_user_trusted_certificates=/etc/grid-security/certificates"
fi

if [ -n "$SRM_CONFIG" ]; then
    if [ ! -f "$SRM_CONFIG" ]; then
        echo "configuration file not found, configuring srm-client" >&2
        mkdir -p "$(dirname $SRM_CONFIG)"

        if runSRM "-save_conf=$SRM_CONFIG" "-urlcopy=$SRM_PATH/sbin/url-copy.sh" "$@"; then
            echo "created configuration file in $SRM_CONFIG" >&2
        fi
    fi

    if [ -f "$SRM_CONFIG" ]; then
        srm_options="-conf=$SRM_CONFIG"
    fi
fi

for arg in "$@"; do
    case "$arg" in
        -delegate|-delegate=true)
            # CBC protection works around the TLS 1.0 BEAST attack; it does this by splitting the first
            # payload into a 1 byte and a n-1 byte chunk. This breaks GSI delegation for JGlobus as
            # JGlobus expects the certificate as a single TLS frame.
            java_options="$java_options -Djsse.enableCBCProtection=false"
            ;;
    esac
done

runSRM "$@"
