#!/usr/bin/env bash

function get_path() {
  cd "$(dirname "$0")"
  cd ..
  echo "$(pwd -P)"
}

KOKKOS_PATH="$(get_path "$0")"

function show_help() {
  local cmd=$(basename "$0")
  echo "Usage: ${cmd} <options> "
  echo "  Build and run the tests"
  echo ""
  echo "Options:"
  echo "  -j=N|--make-j=N        Build the tests in parallel"
  echo "  -c|--clean             Clean build and regenerate make files"
  echo "  --clean-on-pass        Clean build when runtest passes"
  echo "  --output-prefix=<pre>  Prefix of log files  Default: runtest"
  echo "  --build-only           Only build the tests"
  echo "  -v|--verbose           Tee STDOUT and STDERR to screen and files"
  echo "  -h|--help              Show this message"
  echo ""
  ${KOKKOS_PATH}/generate_makefile.bash --help
  return 0
}


declare -a GENERATE_ARGS=()
declare -i VERBOSE=0
declare -i CLEAN=0
declare -i CLEAN_ON_PASS=0
declare -i BUILD_ONLY=0
OUTPUT="runtest"

declare -i MAKE_J=${HPCBIND_NUM_PUS:-1}

for i in $@; do
  case $i in
    -j=*|--make-j=*)
      MAKE_J=${i#*=}
      shift
      ;;
    -c|--clean)
      CLEAN=1
      shift
      ;;
    --clean-on-pass)
      CLEAN_ON_PASS=1
      shift
      ;;
    --output-prefix=*)
      OUTPUT=${i#*=}
      shift
      ;;
    --build-only)
      BUILD_ONLY=1
      shift
      ;;
    -v|--verbose)
      VERBOSE=1
      shift
      ;;
    -h|--help)
      show_help
      exit 0
      ;;
    *)
      GENERATE_ARGS+=("$i")
      shift
      ;;
  esac
done

if [[ "$(pwd -P)" == ${KOKKOS_PATH} ]]; then
  echo "Cannot call $0 from root repository path ${KOKKOS_PATH}"
  exit 1
fi

# Some makefile dependencies are incorrect, so clean needs to force
# a new call to generate_makefiles.bash
if [[ ${CLEAN} -eq 1 ]]; then
  START=${SECONDS}
  echo "Cleaning"
  /bin/rm -rf algorithms containers core example install Makefile >/dev/null 2>&1
  END=${SECONDS}
  echo "    $((END-START)) seconds"
  if [[ ${VERBOSE} -eq 1 ]]; then
    echo ""
    echo ""
  fi
fi

declare -i START=${SECONDS}
echo "Generating Makefile"
echo "    ${KOKKOS_PATH}/generate_makefile.bash --kokkos-path=${KOKKOS_PATH} ${GENERATE_ARGS[@]}"

if [[ ${VERBOSE} -eq 0 ]]; then
  "${KOKKOS_PATH}"/generate_makefile.bash --kokkos-path="${KOKKOS_PATH}" "${GENERATE_ARGS[@]}" > ${OUTPUT}.out 2> >(tee ${OUTPUT}.err >&2)
else
  "${KOKKOS_PATH}"/generate_makefile.bash --kokkos-path="${KOKKOS_PATH}" "${GENERATE_ARGS[@]}" > >(tee ${OUTPUT}.out) 2> >(tee ${OUTPUT}.err >&2)
fi
declare -i RESULT=$?
declare -i END=${SECONDS}
if [[ ${RESULT} -eq 0 ]]; then
  echo "    PASS:  $((END-START)) seconds"
  if [[ ${VERBOSE} -eq 1 ]]; then
    echo ""
    echo ""
  fi
else
  cat ${OUTPUT}.out | grep "FAIL"
  cat ${OUTPUT}.err | grep "FAIL"
  echo "    FAIL:  $((END-START)) seconds"
  exit 1
fi

START=${SECONDS}
echo "Building"
if [[ ${VERBOSE} -eq 0 ]]; then
  make --keep-going -j ${MAKE_J} build-test >> ${OUTPUT}.out 2> >(tee -a ${OUTPUT}.err >&2)
else
  make --keep-going -j ${MAKE_J} build-test > >(tee -a ${OUTPUT}.out) 2> >(tee -a ${OUTPUT}.err >&2)
fi
RESULT=$?
END=${SECONDS}
if [[ ${RESULT} -eq 0 ]]; then
  echo "    PASS:  $((END-START)) seconds"
  if [[ ${VERBOSE} -eq 1 ]]; then
    echo ""
    echo ""
  fi
else
  cat ${OUTPUT}.out | grep -E "[[:space:]]error:[[:space:]]"
  cat ${OUTPUT}.err | grep -E "[[:space:]]error:[[:space:]]"
  echo "    FAIL:  $((END-START)) seconds"
  exit 1
fi

if [[ ${BUILD_ONLY} -eq 0 ]]; then
  START=${SECONDS}
  echo "Testing"
  if [[ ${VERBOSE} -eq 0 ]]; then
    make --keep-going test >> ${OUTPUT}.out 2> >(tee -a ${OUTPUT}.err >&2)
  else
    make --keep-going test > >(tee -a ${OUTPUT}.out) 2> >(tee -a ${OUTPUT}.err >&2)
  fi
  RESULT=$?
  END=${SECONDS}
  if [[ ${RESULT} -eq 0 ]]; then
    echo "    PASS:  $((END-START)) seconds"
    if [[ ${CLEAN_ON_PASS} -eq 1 ]]; then
      make clean
    fi
  else
    cat ${OUTPUT}.out | grep "FAIL"
    cat ${OUTPUT}.err | grep "FAIL"
    echo "    FAIL:  $((END-START)) seconds"
    exit 1
  fi
fi

exit ${RESULT}

