#!/usr/bin/env 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

function start() {
  if [[ -n "${JAVA_OPTS}" ]]; then
      export JAVA_OPTS="${JAVA_OPTS_DEFAULT} ${JAVA_OPTS}"
  else
      export JAVA_OPTS="${JAVA_OPTS_DEFAULT}"
  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}"

  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.2.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
    # shellcheck disable=SC2181
    if [ $? -eq 0 ]; then
      echo "Failed to create user ${MC_ADMIN_USER}." 1>&2
    else
      echo "User ${MC_ADMIN_USER} was created successfully." 1>&2
      exit 1
    fi
  fi

  # 1 -> Java 8 or earlier (1.8..)
  # 9, 10, 11 -> JDK9, JDK10, JDK11 etc.
  JAVA_VERSION=$(java -version 2>&1 | sed -En 's/.* version "([0-9]+).*$/\1/p')
  if [ "$JAVA_VERSION" -ge "9" ]; then
      # --add-opens flag is required to prevent this issue: https://jira.spring.io/browse/SPR-15859
      JAVA_OPTS="--add-opens java.base/java.lang=ALL-UNNAMED ${JAVA_OPTS}"
  fi

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

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

function version(){
  echo "Version: 5.2.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/5.2.1/deploy-manage/system-properties"
  echo " conf   Tool for interacting with Hazelcast Management Center configuration"
}

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

  --version|-V)
      version
      ;;

  start)
      shift
      start "$@"
      ;;

  conf)
      shift
      conf "$@"
      ;;
  *)
     usage
     exit 1
esac
