#!/usr/bin/env bash

set -eux

#/*---------------*\
# *  SETUP VARS   *#
# *---------------*/

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" >& /dev/null && pwd)/../../.."

SBT="$ROOT/project/scripts/sbt" # if run on CI
# SBT="sbt" # if run locally

# set the $DIST_PROJECT and $DIST_DIR variables
source "$ROOT/bin/common-platform"

die () {
    echo >&2 "$@"
    exit 1
}

PROG_HOME="$DIST_DIR/target/universal/stage"

SOURCE="$ROOT/tests/pos/HelloWorld.scala"
SOURCE_VERSION="$ROOT/project/scripts/native-integration/reportScalaVersion.scala"
SOURCE_TEST_BOOTSTRAPPED="$ROOT/project/scripts/native-integration/testBootstrappedLibrary.scala"

clear_cli_dotfiles()
{
  local out="$1"
  rm -rf "$out"/.bsp
  rm -rf "$out"/.scala-build

  rm -f "$ROOT"/.bsp/scala.json
  if [ -z "$(ls -A "$ROOT"/.bsp)" ]; then
    rm -rf "$ROOT"/.bsp
  fi
  rm -rf "$ROOT"/.scala-build
}

#/*---------------*\
# *  INITIALIZE   *#
# *---------------*/

# build the distribution
"$SBT" "$DIST_PROJECT/Universal/stage"

SCALA_VERSION=""
# iterate through lines in VERSION_SRC
while IFS= read -r line; do
  # if line starts with "version:=" then extract the version
  if [[ "$line" == version:=* ]]; then
    SCALA_VERSION="${line#version:=}"
    break
  fi
done < "$PROG_HOME/VERSION"

if [ -z "$SCALA_VERSION" ]; then
  die "Could not find scala version in $PROG_HOME/VERSION"
fi

#/*-------------------*\
# *  TESTING BEGINS   *#
# *-------------------*/

echo "assert native launcher matches expected version"
if [ -z "$LAUNCHER_EXPECTED_PROJECT" ]; then
  die "LAUNCHER_EXPECTED_PROJECT is not set in the environment"
fi
test "$LAUNCHER_EXPECTED_PROJECT" = "$DIST_PROJECT"

echo "testing version output (default)"
std_output=$("$PROG_HOME/bin/scala" version --scala-version)
test "$SCALA_VERSION" = "$std_output"

echo "testing run command"
std_output=$("$PROG_HOME/bin/scala" run "$SOURCE" --power --offline --server=false)
test "hello world" = "$std_output"
clear_cli_dotfiles "$ROOT/tests/pos"

echo "testing run command (-with-compiler)"
std_output=$("$PROG_HOME/bin/scala" run "$SOURCE_VERSION" -with-compiler --power --offline --server=false)
test "$SCALA_VERSION" = "$std_output"
clear_cli_dotfiles "$ROOT/project/scripts/native-integration"

echo "testing REPL direct invocation with -repl-init-script"
# Use scalac with REPL options to verify REPL functionality
# -repl-init-script runs code on startup, -repl-quit-after-init exits after init
std_output=$("$PROG_HOME/bin/scala" -repl-init-script 'println("REPL_INIT_OK"); assert(scala.util.Properties.versionNumberString.startsWith("3."))' -repl-quit-after-init --power --offline --server=false 2>&1)
echo "$std_output" | grep -q "REPL_INIT_OK" || die "REPL init script test failed, output: $std_output"
clear_cli_dotfiles "$ROOT"

echo "testing bootstrapped standard library (scala-library-bootstrapped)"
std_output=$("$PROG_HOME/bin/scala" run "$SOURCE_TEST_BOOTSTRAPPED" --power --offline --server=false)
echo "$std_output" | grep -q "BOOTSTRAPPED_LIBRARY_TEST_PASSED" || die "Bootstrapped library test failed, output: $std_output"
clear_cli_dotfiles "$ROOT/project/scripts/native-integration"

echo "testing REPL does not emit legacy lazy vals warnings on JDK 25 (scala/scala3#25508)"
# The vendored pprint/fansi/sourcecode must be compiled with the new lazy vals
# scheme, otherwise scala.runtime.LazyVals$ calls sun.misc.Unsafe::objectFieldOffset,
# which the JVM reports as a terminally deprecated method starting with JDK 24+
std_output=$("$PROG_HOME/bin/scala" --jvm 25 --server=false -repl-init-script 'val replCheck = 1 + 1' -repl-quit-after-init 2>&1)
echo "$std_output" | grep -q "replCheck" || die "REPL init script did not run on JDK 25, output: $std_output"
if echo "$std_output" | grep "has been called by scala.runtime.LazyVals" | grep -qv "scala-cli"; then
  die "REPL emitted a legacy lazy vals warning on JDK 25, output: $std_output"
fi
clear_cli_dotfiles "$ROOT"

echo "testing REPL coexists with a user dependency on fansi (shaded internally)"
# The REPL vendors pprint/fansi/sourcecode shaded under dotty.vendored.*,
# so a user can depend on the original (unshaded, possibly different-versioned)
# libraries without clashing with the REPL's internal copy.
std_output=$("$PROG_HOME/bin/scala" --server=false --dependency com.lihaoyi::fansi:0.4.0 -repl-init-script 'println(fansi.Color.Red("COEXIST_OK").plainText)' -repl-quit-after-init 2>&1)
echo "$std_output" | grep -q "COEXIST_OK" || die "REPL failed to use a user-provided fansi dependency, output: $std_output"
clear_cli_dotfiles "$ROOT"

