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

BASEDIR=`dirname $0`/..
BASEDIR=`(cd "$BASEDIR"; pwd)`

# OS specific support.  $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
case "`uname`" in
  CYGWIN*) cygwin=true ;;
  Darwin*) darwin=true
           if [ -z "$JAVA_VERSION" ] ; then
             JAVA_VERSION="CurrentJDK"
           else
             echo "Using Java version: $JAVA_VERSION"
           fi
           if [ -z "$JAVA_HOME" ] ; then
             JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/${JAVA_VERSION}/Home
           fi
           ;;
esac

if [ -z "$JAVA_HOME" ] ; then
  if [ -r /etc/gentoo-release ] ; then
    JAVA_HOME=`java-config --jre-home`
  fi
fi

# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
  [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
  [ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi

# If a specific java binary isn't specified search for the standard 'java' binary
if [ -z "$JAVACMD" ] ; then
  if [ -n "$JAVA_HOME"  ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
      # IBM's JDK on AIX uses strange locations for the executables
      JAVACMD="$JAVA_HOME/jre/sh/java"
    else
      JAVACMD="$JAVA_HOME/bin/java"
    fi
  else
    JAVACMD=`which java`
  fi
fi

if [ ! -x "$JAVACMD" ] ; then
  echo "Error: JAVA_HOME is not defined correctly."
  echo "  We cannot execute $JAVACMD"
  exit 1
fi

if [ -z "$REPO" ]
then
  REPO="$BASEDIR"/lib
fi

CLASSPATH=$CLASSPATH_PREFIX
for JAR in $(find "$REPO" -name '*.jar')
do
  CLASSPATH="$CLASSPATH":"$JAR"
done
for JAR in $(find "$BASEDIR"/../../dist/solrj-lib -name '*.jar')
do
  CLASSPATH="$CLASSPATH":"$JAR"
done
for JAR in $(find "$BASEDIR"/../../dist -name 'solr-core-*.jar')
do
  CLASSPATH="$CLASSPATH":"$JAR"
done
for JAR in $(find "$BASEDIR"/../../dist -name 'solr-solrj-*.jar')
do
  CLASSPATH="$CLASSPATH":"$JAR"
done
for JAR in $(find "$BASEDIR"/../../dist -name 'solr-prometheus-exporter-*.jar')
do
  CLASSPATH="$CLASSPATH":"$JAR"
done
for JAR in $(find "$BASEDIR"/lucene-libs -name '*.jar')
do
  CLASSPATH="$CLASSPATH":"$JAR"
done
for JAR in $(find "$BASEDIR"/../../server/solr-webapp/webapp/WEB-INF/lib -name '*.jar')
do
  CLASSPATH="$CLASSPATH":"$JAR"
done

# Memory settings
JAVA_MEM_OPTS=
if [ -z "$JAVA_HEAP" ] && [ -n "$JAVA_MEM" ]; then
  JAVA_MEM_OPTS="$JAVA_MEM"
else
  JAVA_HEAP="${JAVA_HEAP:-512m}"
  JAVA_MEM_OPTS="-Xms$JAVA_HEAP -Xmx$JAVA_HEAP"
fi

# define default GC_TUNE
if [ -z ${GC_TUNE+x} ]; then
    GC_TUNE='-XX:+UseG1GC'
else
    GC_TUNE="$GC_TUNE"
fi

EXTRA_JVM_ARGUMENTS="-Dlog4j.configurationFile=file:"$BASEDIR"/../../server/resources/log4j2-console.xml"

# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
  [ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
  [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
  [ -n "$HOME" ] && HOME=`cygpath --path --windows "$HOME"`
  [ -n "$BASEDIR" ] && BASEDIR=`cygpath --path --windows "$BASEDIR"`
  [ -n "$REPO" ] && REPO=`cygpath --path --windows "$REPO"`
fi

# Convert Environment Variables to Command Line Options
EXPORTER_ARGS=()

if [[ -n "$CONFIG_FILE" ]]; then
  EXPORTER_ARGS+=(-f "$CONFIG_FILE")
fi

if [[ -n "$PORT" ]]; then
  EXPORTER_ARGS+=(-p "$PORT")
fi

if [[ -n "$SCRAPE_INTERVAL" ]]; then
  EXPORTER_ARGS+=(-s "$SCRAPE_INTERVAL")
fi

if [[ -n "$NUM_THREADS" ]]; then
  EXPORTER_ARGS+=(-n "$NUM_THREADS")
fi

if [[ -n "$ZK_HOST" ]]; then
  EXPORTER_ARGS+=(-z "$ZK_HOST")
elif [[ -n "$SOLR_URL" ]]; then
  EXPORTER_ARGS+=(-b "$SOLR_URL")
fi

exec "$JAVACMD" \
  $JAVA_MEM_OPTS \
  $GC_TUNE \
  $JAVA_OPTS \
  $EXTRA_JVM_ARGUMENTS \
  $ZK_CREDS_AND_ACLS \
  -classpath "$CLASSPATH" \
  -Dapp.name="solr-exporter" \
  -Dapp.pid="$$" \
  -Dapp.repo="$REPO" \
  -Dbasedir="$BASEDIR" \
  org.apache.solr.prometheus.exporter.SolrExporter \
  "${EXPORTER_ARGS[@]}" \
  "$@"
