#!/usr/bin/env bash

#/*--------------------------------------------------------------------------
# *  Credits: This script is based on the script generated by sbt-pack.
# *--------------------------------------------------------------------------*/

# save terminal settings
saved_stty=$(stty -g 2>/dev/null)
# clear on error so we don't later try to restore them
if [[ ! $? ]]; then
  saved_stty=""
fi

# restore stty settings (echo in particular)
function restoreSttySettings() {
  stty $saved_stty
  saved_stty=""
}

scala_exit_status=127
function onExit() {
  [[ "$saved_stty" != "" ]] && restoreSttySettings
  exit $scala_exit_status
}

# to reenable echo if we are interrupted before completing.
trap onExit INT TERM EXIT

unset cygwin mingw msys darwin conemu

# COLUMNS is used together with command line option '-pageWidth'.
if command -v tput >/dev/null 2>&1; then
  export COLUMNS="$(tput -Tdumb cols)"
fi

case "`uname`" in
  CYGWIN*) cygwin=true
          ;;
  MINGW*) mingw=true
          ;;
  MSYS*) msys=true
          ;;
  Darwin*) darwin=true
           if [ -z "$JAVA_VERSION" ] ; then
             JAVA_VERSION="CurrentJDK"
           else
            echo "Using Java version: $JAVA_VERSION" 1>&2
           fi
           if [ -z "$JAVA_HOME" ] ; then
             JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/${JAVA_VERSION}/Home
           fi
           JAVACMD="`which java`"
           ;;
esac

unset CYGPATHCMD
if [[ ${cygwin-} || ${mingw-} || ${msys-} ]]; then
  # ConEmu terminal is incompatible with jna-5.*.jar
  [[ (${CONEMUANSI-} || ${ConEmuANSI-}) ]] && conemu=true
  # cygpath is used by various windows shells: cygwin, git-sdk, gitbash, msys, etc.
  CYGPATHCMD=`which cygpath 2>/dev/null`
  case "$TERM" in
    rxvt* | xterm* | cygwin*)
      stty -icanon min 1 -echo
      JAVA_OPTS="$JAVA_OPTS -Djline.terminal=unix"
    ;;
  esac
fi

# Resolve JAVA_HOME from javac command path
if [ -z "$JAVA_HOME" ]; then
  javaExecutable="`which javac`"
  if [ -n "$javaExecutable" -a -f "$javaExecutable" -a ! "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
    # readlink(1) is not available as standard on Solaris 10.
    readLink=`which readlink`
    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
      javaExecutable="`readlink -f \"$javaExecutable\"`"
      javaHome="`dirname \"$javaExecutable\"`"
      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
      JAVA_HOME="$javaHome"
      export JAVA_HOME
    fi
  fi
fi

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 "$JAVA_HOME" ] ; then
  echo "Warning: JAVA_HOME environment variable is not set."
fi

CLASSPATH_SUFFIX=""
# Path separator used in EXTRA_CLASSPATH
PSEP=":"

# translate paths to Windows-mixed format before running java
if [ -n "${CYGPATHCMD-}" ]; then
  [ -n "${PROG_HOME-}" ] &&
    PROG_HOME=`"$CYGPATHCMD" -am "$PROG_HOME"`
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME=`"$CYGPATHCMD" -am "$JAVA_HOME"`
  CLASSPATH_SUFFIX=";"
  PSEP=";"
elif [[ ${mingw-} || ${msys-} ]]; then
  # For Mingw / Msys, convert paths from UNIX format before anything is touched
  [ -n "$PROG_HOME" ] &&
    PROG_HOME="`(cd "$PROG_HOME"; pwd -W | sed 's|/|\\\\|g')`"
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME="`(cd "$JAVA_HOME"; pwd -W | sed 's|/|\\\\|g')`"
  CLASSPATH_SUFFIX=";"
  PSEP=";"
fi

#/*--------------------------------------------------
# * The code below is for Dotty
# *-------------------------------------------------*/

find_lib () {
  for lib in "$PROG_HOME"/lib/$1 ; do
    if [[ -f "$lib" ]]; then
      if [ -n "$CYGPATHCMD" ]; then
        "$CYGPATHCMD" -am "$lib"
      elif [[ $mingw ||  $msys ]]; then
        echo "$lib" | sed 's|/|\\\\|g'
      else
        echo "$lib"
      fi
      return
    fi
  done
}

DOTTY_COMP=$(find_lib "*scala3-compiler*")
DOTTY_INTF=$(find_lib "*scala3-interfaces*")
DOTTY_LIB=$(find_lib "*scala3-library*")
DOTTY_STAGING=$(find_lib "*scala3-staging*")
DOTTY_TASTY_INSPECTOR=$(find_lib "*scala3-tasty-inspector*")
TASTY_CORE=$(find_lib "*tasty-core*")
SCALA_ASM=$(find_lib "*scala-asm*")
SCALA_LIB=$(find_lib "*scala-library*")
SBT_INTF=$(find_lib "*compiler-interface*")
JLINE_READER=$(find_lib "*jline-reader-3*")
JLINE_TERMINAL=$(find_lib "*jline-terminal-3*")
JLINE_TERMINAL_JNA=$(find_lib "*jline-terminal-jna-3*")

# jna-5 only appropriate for some combinations
[[ ${conemu-} && ${msys-} ]] || JNA=$(find_lib "*jna-5*")

compilerJavaClasspathArgs () {
  # echo "dotty-compiler: $DOTTY_COMP"
  # echo "dotty-interface: $DOTTY_INTF"
  # echo "dotty-library: $DOTTY_LIB"
  # echo "tasty-core: $TASTY_CORE"
  # echo "scala-asm: $SCALA_ASM"
  # echo "scala-lib: $SCALA_LIB"
  # echo "sbt-intface: $SBT_INTF"

  toolchain=""
  toolchain+="$SCALA_LIB$PSEP"
  toolchain+="$DOTTY_LIB$PSEP"
  toolchain+="$SCALA_ASM$PSEP"
  toolchain+="$SBT_INTF$PSEP"
  toolchain+="$DOTTY_INTF$PSEP"
  toolchain+="$DOTTY_COMP$PSEP"
  toolchain+="$TASTY_CORE$PSEP"
  toolchain+="$DOTTY_STAGING$PSEP"
  toolchain+="$DOTTY_TASTY_INSPECTOR$PSEP"

  # jine
  toolchain+="$JLINE_READER$PSEP"
  toolchain+="$JLINE_TERMINAL$PSEP"
  toolchain+="$JLINE_TERMINAL_JNA$PSEP"
  [ -n "${JNA-}" ] && toolchain+="$JNA$PSEP"

  if [ -n "${jvm_cp_args-}" ]; then
    jvm_cp_args="$toolchain$jvm_cp_args"
  else
    jvm_cp_args="$toolchain$PSEP"
  fi
}

default_java_opts="-Xmx768m -Xms768m"

CompilerMain=dotty.tools.dotc.Main
DecompilerMain=dotty.tools.dotc.decompiler.Main
TastyPrinterMain=dotty.tools.dotc.core.tasty.TastyPrinter
ReplMain=dotty.tools.repl.Main
ScriptingMain=dotty.tools.scripting.Main

declare -a java_args
declare -a scala_args
declare -a residual_args
declare -a script_args

addJava () {
  java_args+=("'$1'")
}
addScala () {
  scala_args+=("'$1'")
}
addResidual () {
  residual_args+=("'$1'")
}
addScript () {
  script_args+=("'$1'")
}
