#!/usr/bin/env bash

#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

set -e

BASE_DIR=$(pwd)

SOURCE="${BASH_SOURCE[0]}"
while [[ -h "$SOURCE" ]]; do # resolve $SOURCE until the file is no longer a symlink
  SCRIPTDIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
SCRIPTDIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"

function changes_for_path() {
  pushd geode >> /dev/null
    local path="$1" # only expand once in the line below
    # Get the last release tag on the branch
    local releaseTag=$(git describe --abbrev=0 --tags)
    local releaseBase=$(git rev-list -n 1 $releaseTag) || exit $?

    if [[ "${releaseBase}" == "" ]]; then
      echo "Could not determine release base. Exiting..."
      exit 1
    fi
    git diff --name-only ${releaseBase} -- $path
  popd >> /dev/null
}

UNIT_TEST_CHANGES=$(changes_for_path '*/src/test/java') || exit $?
INTEGRATION_TEST_CHANGES=$(changes_for_path '*/src/integrationTest/java') || exit $?
DISTRIBUTED_TEST_CHANGES=$(changes_for_path '*/src/distributedTest/java') || exit $?
ACCEPTANCE_TEST_CHANGES=$(changes_for_path '*/src/acceptanceTest/java') || exit $?
UPGRADE_TEST_CHANGES=$(changes_for_path '*/src/upgradeTest/java') || exit $?

CHANGED_FILES_ARRAY=( $UNIT_TEST_CHANGES $INTEGRATION_TEST_CHANGES $DISTRIBUTED_TEST_CHANGES $ACCEPTANCE_TEST_CHANGES $UPGRADE_TEST_CHANGES )
NUM_CHANGED_FILES=${#CHANGED_FILES_ARRAY[@]}

echo "${NUM_CHANGED_FILES} changed tests"

if [[  "${NUM_CHANGED_FILES}" -eq 0 ]]
then
  echo "No changed test files, nothing to test."
  exit 0
fi

if [[ "${NUM_CHANGED_FILES}" -gt 25 ]]
then
  echo "${NUM_CHANGED_FILES} is too many changed tests to stress test. Allowing this job to pass without stress testing."
  exit 0
fi

TEST_TARGETS=""

function append_to_test_targets() {
  local target="$1"
  local files="$2"
  if [[ -n "$files" ]]
  then
    TEST_TARGETS="$TEST_TARGETS $target"
    for FILENAME in $files
    do
      SHORT_NAME=$(basename $FILENAME)
      SHORT_NAME="${SHORT_NAME%.java}"
      TEST_TARGETS="$TEST_TARGETS --tests $SHORT_NAME"
    done
  fi
}

append_to_test_targets "repeatUnitTest" "$UNIT_TEST_CHANGES"
append_to_test_targets "repeatIntegrationTest" "$INTEGRATION_TEST_CHANGES"
append_to_test_targets "repeatDistributedTest" "$DISTRIBUTED_TEST_CHANGES"
append_to_test_targets "repeatUpgradeTest" "$UPGRADE_TEST_CHANGES"

# Acceptance tests cannot currently run in parallel, so do not stress these tests
#append_to_test_targets "repeatAcceptanceTest" "$ACCEPTANCE_TEST_CHANGES"

export GRADLE_TASK="compileTestJava compileIntegrationTestJava compileDistributedTestJava $TEST_TARGETS"
export GRADLE_TASK_OPTIONS="--no-parallel -Prepeat=50 -PfailOnNoMatchingTests=false"

echo "---------------------------------------------------"
echo "GRADLE_TASK_OPTIONS=${GRADLE_TASK_OPTIONS}"
echo "GRADLE_TASK=${GRADLE_TASK}"
echo "---------------------------------------------------"

REPODIR=$(cd geode; git rev-parse --show-toplevel)

if [[ ${PARALLEL_GRADLE:-"true"} == "true" ]]; then
  PARALLEL_GRADLE="--parallel"
else
  PARALLEL_GRADLE="--no-parallel"
fi
DEFAULT_GRADLE_TASK_OPTIONS="${PARALLEL_GRADLE} --console=plain --no-daemon"
GRADLE_SKIP_TASK_OPTIONS="-x javadoc -x spotlessCheck -x rat"

if [[ -n "${PARALLEL_DUNIT}" && "${PARALLEL_DUNIT}" == "true" ]]; then
  PARALLEL_DUNIT="-PparallelDunit"
  if [ -n "${DUNIT_PARALLEL_FORKS}" ]; then
    DUNIT_PARALLEL_FORKS="--max-workers=${DUNIT_PARALLEL_FORKS} -PtestMaxParallelForks=${DUNIT_PARALLEL_FORKS} -PdunitParallelForks=${DUNIT_PARALLEL_FORKS}"
  fi
else
  PARALLEL_DUNIT=""
  DUNIT_PARALLEL_FORKS=""
fi

case $ARTIFACT_SLUG in
  windows*)
    echo "Making environment adjustments for windows."
    JAVA_BUILD_PATH=C:/java${JAVA_BUILD_VERSION}
    JAVA_TEST_PATH=C:/java${JAVA_TEST_VERSION}
    TEST_JAVA_8_HOME=C:/java8
    TEST_JAVA_11_HOME=C:/java11
    TEST_JAVA_17_HOME=C:/java17
    GRADLE_SKIP_TASK_OPTIONS="${GRADLE_SKIP_TASK_OPTIONS} -x docker"
    SEP=";"
    OPTIONAL_KILL_ALL_CMD="${SEP} \
      exit_code=\$? ${SEP} \
      (taskkill //F //IM java.exe //T) ${SEP} \
      exit \${exit_code}
      "
    ;;
  *)
    JAVA_BUILD_PATH=/usr/lib/jvm/java-${JAVA_BUILD_VERSION}-openjdk-amd64
    JAVA_TEST_PATH=/usr/lib/jvm/java-${JAVA_TEST_VERSION}-openjdk-amd64
    TEST_JAVA_8_HOME=/usr/lib/jvm/java-8-openjdk-amd64
    TEST_JAVA_11_HOME=/usr/lib/jvm/java-11-openjdk-amd64/
    TEST_JAVA_17_HOME=/usr/lib/jvm/java-17-openjdk-amd64/
    SEP="&&"
    ;;
esac

GRADLE_ARGS=" \
    -PcompileJVM=${JAVA_BUILD_PATH} \
    -PcompileJVMVer=${JAVA_BUILD_VERSION} \
    -PtestJVM=${JAVA_TEST_PATH} \
    -PtestJVMVer=${JAVA_TEST_VERSION} \
    -PtestJava8Home=${TEST_JAVA_8_HOME} \
    -PtestJava11Home=${TEST_JAVA_11_HOME} \
    -PtestJava17Home=${TEST_JAVA_17_HOME} \
    ${PARALLEL_DUNIT} \
    ${DUNIT_PARALLEL_FORKS} \
    ${DEFAULT_GRADLE_TASK_OPTIONS} \
    ${GRADLE_SKIP_TASK_OPTIONS} \
    ${GRADLE_TASK} \
    ${GRADLE_TASK_OPTIONS} \
    ${GRADLE_GLOBAL_ARGS}"

EXEC_COMMAND="bash -c 'echo Building with: $SEP \
  ${JAVA_BUILD_PATH}/bin/java -version $SEP \
  echo Testing with: $SEP \
  ${JAVA_TEST_PATH}/bin/java -version $SEP \
  cd geode $SEP \
  cp gradlew gradlewStrict $SEP \
  sed -e 's/JAVA_HOME/GRADLE_JVM/g' -i.bak gradlewStrict $SEP \
  GRADLE_JVM=${JAVA_BUILD_PATH} JAVA_TEST_PATH=${JAVA_TEST_PATH} ./gradlewStrict ${GRADLE_ARGS}'"
echo "${EXEC_COMMAND}"
eval "${EXEC_COMMAND}"


