#!/usr/bin/bash

set -eo pipefail

function append_min_max_heapsize() {
  if [ -n "${MIN_HEAP_SIZE}" ]; then
      export JAVA_OPTS="${JAVA_OPTS} -Xms${MIN_HEAP_SIZE}"
  fi
  if [ -n "${MAX_HEAP_SIZE}" ]; then
      export JAVA_OPTS="${JAVA_OPTS} -Xmx${MAX_HEAP_SIZE}"
  fi
}

function findScriptDir() {
  CURRENT=$PWD

  DIR=$(dirname "$0")
  cd "$DIR" || exit
  TARGET_FILE=$(basename "$0")

  # Iterate down a (possible) chain of symlinks
  while [ -L "$TARGET_FILE" ]
  do
      TARGET_FILE=$(readlink "$TARGET_FILE")
      DIR=$(dirname "$TARGET_FILE")
      cd "$DIR" || exit
      TARGET_FILE=$(basename "$TARGET_FILE")
  done

  SCRIPT_DIR=$(pwd -P)
  # Restore current directory
  cd "$CURRENT" || exit
}

findScriptDir

if [ "$JAVA_HOME" ]; then
    JAVA="$JAVA_HOME/bin/java"
else
    JAVA="$(command -v java 2>/dev/null)"
fi

if [ -z "$JAVA" ]; then
    echo "Cannot find a way to start the JVM: neither JAVA_HOME is set nor the java command is on the PATH"
    exit 1
fi

if [[ -n "${JAVA_OPTS}" ]]; then
    export JAVA_OPTS="${JAVA_OPTS_DEFAULT} ${JAVA_OPTS}"
else
    export JAVA_OPTS="${JAVA_OPTS_DEFAULT}"
fi

function start() {
  # --add-opens flag is required to prevent this issue: https://jira.spring.io/browse/SPR-15859
  # --add-opens flags for suppressing illegal access warn for jdk 11.0.19

  JAVA_OPTS="\
         --add-opens java.base/java.lang=ALL-UNNAMED \
         --add-opens java.base/sun.nio.ch=ALL-UNNAMED ${JAVA_OPTS} \
      "

  VM_NAME="$(${JAVA} -XshowSettings:properties -version 2>&1 | grep java.vm.name | cut -d "=" -f2)"
  if [[ "$VM_NAME" =~ "OpenJ9" ]]; then
    JAVA_OPTS="--add-exports jdk.management/com.ibm.lang.management.internal=ALL-UNNAMED ${JAVA_OPTS}"
  fi

  if [ -n "${LOGGING_LEVEL}" ]; then
      export JAVA_OPTS="-Dhazelcast.mc.log.level=${LOGGING_LEVEL} ${JAVA_OPTS}"
  fi
  # unset to not break spring boot config binding
  unset LOGGING_LEVEL

  JAVA_OPTS="$* ${JAVA_OPTS}"

  upgradeH2

  if [[ "$OSTYPE" =~ ^linux ]]; then
    # UseContainerSupport is a linux-only java feature
    if [ "${CONTAINER_SUPPORT:-false}" = "false" ] ;then
        echo "Container support disabled. Using manual heap sizing by specifying MIN_HEAP_SIZE, MAX_HEAP_SIZE or custom settings configured by JAVA_OPTS." 1>&2
        append_min_max_heapsize;
    else
        echo "Container support enabled. Using automatic heap sizing. JVM will use up to 80% of the memory limit of the host." 1>&2
        export JAVA_OPTS="${JAVA_OPTS} -XX:+UseContainerSupport -XX:MaxRAMPercentage=80"
    fi
  else
    append_min_max_heapsize;
  fi

  # shellcheck disable=SC2154
  export MC_RUNTIME="${SCRIPT_DIR}/../hazelcast-management-center-5.5.1.jar"
  export USER_LIB="${SCRIPT_DIR}/user-lib/*"
  if [ -n "${MC_CLASSPATH}" ]; then
      export MC_CLASSPATH="${MC_CLASSPATH//:/,},${USER_LIB}"
  else
      export MC_CLASSPATH="${USER_LIB}"
  fi

  if [ -n "${MC_INIT_CMD}" ]; then
     echo "Executing command specified by MC_INIT_CMD." 1>&2
     eval "${MC_INIT_CMD}"
  fi

  if [ -n "${MC_INIT_SCRIPT}" ]; then
      echo "Loading script $MC_INIT_SCRIPT specified by MC_INIT_SCRIPT." 1>&2
      # shellcheck source=/dev/null
      source "${MC_INIT_SCRIPT}"
  fi

  if [ -n "${MC_ADMIN_USER}" ] && [ -n "${MC_ADMIN_PASSWORD}" ]; then
    echo "Creating admin user."  1>&2
    source "${SCRIPT_DIR}"/mc-conf.sh user create --lenient=true -n="${MC_ADMIN_USER}" -p="${MC_ADMIN_PASSWORD}" -r=admin
    if [ $? -ne 0 ]; then
      echo "Failed to create user ${MC_ADMIN_USER}." 1>&2
      exit 1
    fi
  fi

  set -x
  # shellcheck disable=SC2086
  exec java \
      -server \
      -Dloader.path="${MC_CLASSPATH}" \
      ${JAVA_OPTS} \
      -cp "${MC_RUNTIME}" \
      org.springframework.boot.loader.launch.PropertiesLauncher
}

function conf() {
  source "${SCRIPT_DIR}"/mc-conf.sh "$@"
}

function upgradeH2() {
  h2UpgradeJar="${SCRIPT_DIR}/../h2-upgrade-cli-5.5.1.jar"

  if [ -f "$h2UpgradeJar" ]; then
    local overwriteFlag=""
    if [ "$1" == "--overwrite" ]; then
      overwriteFlag="$1"
      shift
    fi
    java -jar ${JAVA_OPTS} "$h2UpgradeJar" upgrade $overwriteFlag "$@"
  fi
}

function version(){
  echo "Version: 5.5.1"
}

function usage() {
  echo "Global options are:"
  echo "  -h, --help      Show this help message and exit."
  echo "  -V, --version   Print version information and exit."
  echo "Commands"
  echo " start     <java options> Starts Hazelcast Management Center.
  More information: https://docs.hazelcast.com/management-center/$(echo "5.5.1" | awk -F'.' '{print $1"."$2}')/deploy-manage/system-properties"
  echo " conf      Tool for interacting with Hazelcast Management Center configuration"
  echo " upgrade-h2 Migrates H2 db data from previous Management Center installation and overwrites existing \${hazlecast.mc.home}/metadata directory"
}

case "$1" in
  --help|-h)
      usage
      ;;

  --version|-V)
      version
      ;;

  start)
      shift
      start "$@"
      ;;

  conf)
      shift
      conf "$@"
      ;;

  upgrade-h2)
      shift
      upgradeH2 --overwrite "$@"
      ;;

  *)
     usage
     exit 1
esac
