#!/bin/bash
# to be run in Docker-Container in sh
# assumes that
# - the project to be tested is in a mounted folder called `testee``
# - the project with the check tests is in a mounted folder called `check`
# - a folder `report` ist mounted to which unit and coverage reports are written
# - a folder `clip` is mounted (for temporare backups)

# cf. https://superuser.com/questions/878640/unix-script-wait-until-a-file-exists
# Block until the given file appears or the given timeout is reached.
# Exit status is 0 iff the file exists.
# Simplified to fit out needs here
wait_file() {
  local file="$1"; shift
  local wait_seconds=4
  until test $((wait_seconds--)) -eq 0 -o -e "$file" ; do sleep 1; done
  test $wait_seconds -ge 0
}

# for debug purposes:
#set -x

OFFLINEMODE="--prefer-offline" # "--offline" (requires cache) or "--prefer-offline" or nothing (empty)
TIMEOUT_STUDENT_TESTRUN=120s # timeout for student tests (all of them)
TIMEOUT_CHECK_TESTRUN=120s # timeout for check tests (all of them)
CHECKPACKAGESARR=(
    "typescript"
    "jest"
    "jest-junit"
    "ts-jest"
    "@types/jest"
    "@types/node"
    "metamatcher"
)
CHECKPACKAGES=$(printf " %s" "${CHECKPACKAGESARR[@]}")

echo "-------- Run check for user $SUBMISSIONID in Docker, run as $(whoami) ------------"
cd testee
echo "1. Install, build  ........................................................."
for dir in "coverage" "out" "dist" "build" ; do
    [ -d "$dir" ] && rm -rf "$dir"
done

# enforce required packages (jest-junit and others) to be present
npm install $OFFLINEMODE --no-audit --no-fund --save-dev $CHECKPACKAGES
npm run build

echo "2. Run student tests ......................................................."
timeout $TIMEOUT_STUDENT_TESTRUN npx jest -rundInBand --coverage=true --reporters="default" --reporters="jest-junit" --silent --forceExit

echo "3. Copy student test results to /reports ..................................."
wait_file "junit.xml" && cp junit.xml "/reports/_${SUBMISSIONID}_junit.student.xml"
[ ! -f "junit.xml" ] && echo "No test report found for student tests!"
wait_file "coverage/clover.xml" && cp coverage/clover.xml "/reports/_${SUBMISSIONID}_coverage.student.xml"
[ ! -f "coverage/clover.xml" ] && echo "No coverage report found for student tests!"

echo "4. Prepare check tests ....................................................."
[ -f "junit.xml" ] && rm junit.xml # created during check tests, we wait for that file later on!
if [[ "${SUBMISSIONID}" != "solution" ]]; then 
    # delete, otherwise cp creates a new subfolder (required for checking a single user)
    [ -d "/check/tests" ] && rm -rf check
    [ ! -d "check" ] && mkdir check
    [ -d "/check/tests" ] && cp -r /check/tests check/tests
else
    echo "Do not copy test checks, running on solution"
fi
[ ! -d "out" ] && mkdir out

echo "5. Run check tests ........................................................."
export JEST_JUNIT_SUITE_NAME="{filename}"
[ ! -f "check/tests/jest.check.config.js" ] && echo "No check tests config 'check/tests/jest.check.config.js' found."
timeout $TIMEOUT_CHECK_TESTRUN npx jest --runInBand --config check/tests/jest.check.config.js --forceExit

echo "6. Copy check tests results to /reports  ..................................."
wait_file "junit.xml" && cp junit.xml "/reports/_${SUBMISSIONID}_junit.check.xml"
[ ! -f "junit.xml" ] && echo "No test report found for check tests!"

echo "6.1. Copy out (screenshots)................................................"
[ -d "out" ] && rm -rf "/reports/_${SUBMISSIONID}_img"
[ -d "out" ] && cp -r out "/reports/_${SUBMISSIONID}_img"


echo "7. Clean up  ..............................................................."
for dir in "coverage" "out" "dist" "build" ; do
    [ -d "$dir" ] && rm -rf "$dir"
done
for file in "junit.xml" ; do
    [ -f "$file" ] && rm "$file"
done

echo "-------------------------------- DONE --------------------------------------"
