#!/usr/bin/env bash

function cd_or_die() {
  cd "$1" || (echo "Can't cd to $1" >&2; exit 3)
}

# Limit virtual memory on docker
export MALLOC_ARENA_MAX=4

CURDIR="${PWD}"

#REALPATH=$(readlink -f $0)
#LOCATION=$(dirname "$REALPATH")

#readlink -f does not work on mac, use alternate script
TARGET_FILE=$0

cd_or_die "$(dirname "${TARGET_FILE}")"
TARGET_FILE="$(basename "${TARGET_FILE}")"

# Iterate down a (possible) chain of symlinks
while [ -L "${TARGET_FILE}" ]
do
    TARGET_FILE="$(readlink "${TARGET_FILE}")"
    cd_or_die "$(dirname "${TARGET_FILE}")"
    TARGET_FILE="$(basename "${TARGET_FILE}")"
done

REALPATH=$TARGET_FILE
#end of readlink -f

LOCATION=$( cd_or_die "$(dirname "${REALPATH}")" ; pwd -P )
cd_or_die "$CURDIR"

MEM=${OPENMOLE_MEMORY:-"2G"}
# enable through command line arguments --debug and --debug-port
DEBUG_MODE=false
DEBUG_PORT=5005

JAVA="java"
if [ ! -z ${JAVA_HOME} ]
then
  # the environment variable is defined
  if [ -e ${JAVA_HOME}/bin/java ]
  then
      # and this folder does exist
      #echo "using java ${JAVA_HOME}/bin/java"
      JAVA="${JAVA_HOME}/bin/java"
  else
      echo "wrong java home ${JAVA_HOME}; falling back to 'java'"
  fi
fi

FLAGS=()
FLAGS+=("-XX:+UseCompressedOops")
FLAGS+=("-XX:+UseCompressedClassPointers")

JVMVERSION=$($JAVA -version 2>&1 | awk -F '"' '/version/ {print $2}')
if [[ "$JVMVERSION" == 1.* ]]; then
  MAJOR_VERSION=$(echo "$JVMVERSION" | cut -d. -f2)
else
  MAJOR_VERSION=$(echo "$JVMVERSION" | cut -d. -f1)
fi


if (( MAJOR_VERSION < 21 )); then
  echo "Your Java version is too old ($JVMVERSION). Please use Java 21 or newer."
  exit 1
fi

if (( MAJOR_VERSION >= 24 )); then
  FLAGS+=("-XX:+UnlockExperimentalVMOptions")
  FLAGS+=("-XX:+UseCompactObjectHeaders")
fi

WORKSPACE="${HOME}/.openmole"

ARGS=()
SCRIPT_ARGS=()

function usage() {
cat <<EOF
OpenMOLE launch script options:
  -d   --debug          Enable remote debugging (for developers)
  -h   --help           Show this message
  -m   --mem            Set OpenMOLE application's memory (default: --mem ${MEM})
  -p   --debug-port     Set port for remote debugging (default: --debug-port ${DEBUG_PORT})

EOF
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    -d|--debug ) DEBUG_MODE=true ;;
    h|--help ) usage ; ARGS+=("--help") ;;
    m|--mem ) MEM="$2" ; shift ;;
    --debug-port ) DEBUG_PORT="$2"; shift ;;
    w|--workspace ) WORKSPACE="$2"; shift ; ARGS+=("--workspace"); ARGS+=("${WORKSPACE}") ;;
    * ) ARGS+=("$1");;
  esac
  shift 
done

if [ ${DEBUG_MODE} == true ]; then
  FLAGS+=("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=${DEBUG_PORT}")
fi

# Try to increase the max number of opened files
if [[ $(ulimit -S -n) -lt 4096 ]]; then ulimit -S -n 4096 2>/dev/null; fi

CONFIGDIR=$(mktemp -d)

exec $JAVA -Xss8M -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -Duser.country=US -Duser.language=en -Djava.security.egd=file:/dev/./urandom -Dopenmole.location="${LOCATION}" -Dosgi.classloader.singleThreadLoads=true -Dosgi.configuration.area="${CONFIGDIR}" -Djdk.util.zip.disableZip64ExtraFieldValidation=true "-Xmx${MEM}" "${FLAGS[@]}" \
   -XX:+UseG1GC -XX:CICompilerCount=2 -XX:ParallelGCThreads=2 -XX:ConcGCThreads=2 -XX:G1ConcRefinementThreads=2 -XX:+UseStringDeduplication \
   --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.nio.file=ALL-UNNAMED \
   -cp "${LOCATION}/launcher/*" org.openmole.launcher.Launcher  --plugins "${LOCATION}/plugins/" --priority "logging" --run org.openmole.ui.Application --osgi-directory "${CONFIGDIR}" -- \
   "${ARGS[@]}" "${SCRIPT_ARGS[@]}"
