#!/usr/bin/env bash
#
# Rumi CLI launcher
# Prefers `java` on PATH (>= 11). If unavailable or < 11, try JAVA_HOME (>= 11).
# Includes required --add-opens flags; allows user extras via JAVA_OPTS (cannot override required flags).
#

set -euo pipefail

MIN_MAJOR=11

# ---------------------------------------------------------------------------
# Parse arguments
EXTRA_JARS=""
ENABLE_3X="false"
POSITIONAL_ARGS=()

while [[ $# -gt 0 ]]; do
  case "$1" in
    --extra-jars)
      EXTRA_JARS=$2
      shift 2
      ;;
    --3x)
      ENABLE_3X="true"
      shift
      ;;
    *)
      POSITIONAL_ARGS+=("$1")
      shift
      ;;
  esac
done

# Restore positional parameters
set -- "${POSITIONAL_ARGS[@]}"

# ---------------------------------------------------------------------------
# User-provided extras: keep empty by default, safe with `set -u`
# Placed BEFORE required opts so user cannot override required ones.
: "${JAVA_OPTS:=}"

# ---------------------------------------------------------------------------
# Helpers
get_java_major() {
  # Prints the Java "major" version number (e.g. 17 for 17.0.9; 8 for 1.8.0_x)
  local jbin="$1"
  local v
  v="$("$jbin" -version 2>&1 | awk -F '"' '/version/ {print $2}' || true)"
  if [[ -z "${v:-}" ]]; then
    echo ""
    return 1
  fi
  if [[ "$v" == 1.* ]]; then
    echo "${v#1.}" | cut -d. -f1
  else
    echo "$v" | cut -d. -f1
  fi
}

require_java_11_plus() {
  # Sets CHOSEN_JAVA to a valid java (>=11), or prints error and exits.
  local path_java=""
  local path_major=""
  local home_java=""
  local home_major=""

  if command -v java >/dev/null 2>&1; then
    path_java="$(command -v java)"
    path_major="$(get_java_major "$path_java" || true)"
  fi

  if [[ -n "${path_major:-}" && "$path_major" =~ ^[0-9]+$ && "$path_major" -ge $MIN_MAJOR ]]; then
    CHOSEN_JAVA="$path_java"
    return 0
  fi

  if [[ -n "${JAVA_HOME:-}" && -x "$JAVA_HOME/bin/java" ]]; then
    home_java="$JAVA_HOME/bin/java"
    home_major="$(get_java_major "$home_java" || true)"
    if [[ -n "${home_major:-}" && "$home_major" =~ ^[0-9]+$ && "$home_major" -ge $MIN_MAJOR ]]; then
      CHOSEN_JAVA="$home_java"
      return 0
    fi
  fi

  {
    echo "Error: Java $MIN_MAJOR or newer is required."
    if [[ -n "${path_java:-}" ]]; then
      if [[ -n "${path_major:-}" ]]; then
        echo " - Found java on PATH: $path_java (version: $path_major) — not sufficient."
      else
        echo " - Found java on PATH: $path_java, but could not determine version."
      fi
    else
      echo " - No 'java' found on PATH."
    fi
    if [[ -n "${JAVA_HOME:-}" ]]; then
      if [[ -x "$JAVA_HOME/bin/java" ]]; then
        if [[ -n "${home_major:-}" ]]; then
          echo " - JAVA_HOME points to: $JAVA_HOME (version: $home_major) — not sufficient."
        else
          echo " - JAVA_HOME points to: $JAVA_HOME, but could not determine version."
        fi
      else
        echo " - JAVA_HOME is set to '$JAVA_HOME' but '$JAVA_HOME/bin/java' is missing or not executable."
      fi
    else
      echo " - JAVA_HOME is not set (optional; only needed if PATH java is missing or too old)."
    fi
    echo ""
    echo "Fix:"
    echo "  * Install Java $MIN_MAJOR+ and ensure 'java' is on your PATH, OR"
    echo "  * Set JAVA_HOME to a Java $MIN_MAJOR+ installation (with \$JAVA_HOME/bin/java)."
  } >&2
  exit 1
}

# ---------------------------------------------------------------------------
# Select Java
CHOSEN_JAVA=""
require_java_11_plus

# ---------------------------------------------------------------------------
# Resolve RUMI_CLI_HOME (follow symlinks)
SOURCE="${BASH_SOURCE[0]}"
while [[ -h "$SOURCE" ]]; do # resolve $SOURCE until file is no longer a symlink
  DIR="$(cd -P "$(dirname -- "$SOURCE")" >/dev/null 2>&1 && pwd)"
  TARGET="$(readlink -- "$SOURCE")"
  [[ "$TARGET" != /* ]] && SOURCE="$DIR/$TARGET" || SOURCE="$TARGET"
done
SCRIPT_DIR="$(cd -P "$(dirname -- "$SOURCE")" >/dev/null 2>&1 && pwd)"
export RUMI_CLI_HOME="$(cd -P "$SCRIPT_DIR/.." >/dev/null 2>&1 && pwd)"

# ---------------------------------------------------------------------------
# Config
RUMI_CLI_PROPFILE="$RUMI_CLI_HOME/conf/cli.conf"
DEFAULTTRACELEVEL=severe

# Required --add-opens (array form, so they can't be altered by user quoting)
REQUIRED_OPTS=(
  --add-opens=java.base/jdk.internal.ref=ALL-UNNAMED
  --add-opens=java.base/sun.nio.ch=ALL-UNNAMED
  --add-opens=java.base/java.lang=ALL-UNNAMED
  --add-opens=java.base/java.nio=ALL-UNNAMED
  --add-opens=java.base/java.io=ALL-UNNAMED
  --add-opens=java.management/sun.management=ALL-UNNAMED
)

# Build classpath
CLASSPATH="$RUMI_CLI_HOME/libs/*"

if [[ -n "$EXTRA_JARS" ]]; then
  IFS=',' read -ra JARS <<< "$EXTRA_JARS"
  for jar in "${JARS[@]}"; do
    CLASSPATH="$CLASSPATH:$jar"
  done
fi

# Add 3.x compatibility if requested
COMPAT_3X_OPT=""
if [[ "$ENABLE_3X" == "true" ]]; then
  COMPAT_3X_OPT="-Dnv.compat.3x.io=true"
fi

# ---------------------------------------------------------------------------
# Run
exec "$CHOSEN_JAVA" \
  -Xms1g -Xmx1g \
  ${JAVA_OPTS:-} \
  "${REQUIRED_OPTS[@]}" \
  ${COMPAT_3X_OPT} \
  -Dnv.app.propfile="$RUMI_CLI_PROPFILE" \
  -Dnv.trace.defaultLevel="$DEFAULTTRACELEVEL" \
  -Dnv.cloud.trace=info \
  -Djava.net.preferIPv4Stack=true \
  -cp "$CLASSPATH" \
  com.neeve.tools.CliMain "$@"
