#!/bin/bash
#usage : script [-c -l -n -s -k] testsuite_dir

##########################
####   LAUNCH CTEST   ####
##########################

export SHOW_PROGRESS=""
export KEEP_TESTS=""
export DO_NOT_UPLOAD=""
export DO_NOT_TEST=""
export CGAL_URL="https://cgal.geometryfactory.com/CGAL/Releases"
export UPLOAD_RESULT_DESTINATION="cgaltest@cgaltest.geometryfactory.com:incoming"
export UPLOAD_DEMOS_DESTINATION="cgaltest@cgaltest.geometryfactory.com:public_html/incoming"
export LATEST_LOCATION="${CGAL_URL}/LATEST"
export TAR="tar"
export GUNZIP="gunzip"
export COMPRESSOR="gzip"
export CONSOLE_OUTPUT="y"
CGAL_HOME=$(pwd | sed -E 's/\/cygdrive\/([a-z])\//\U\1:\//')
export CGAL_HOME
export USE_TARGZ="y"
export USE_TARBZ="n"
export CGAL_RELEASE=""
export LOGS_DIR=""
export LOCK_FILE=""
export ACTUAL_LOGFILE=""
export CGAL_DIR=""
export INSTALLATION_DIR=""
export TESTSUITE_DIR=""
USE_LATEST_UNZIPPED=""

WGET="wget"
WGET_OPTS=(--no-check-certificate --no-verbose)
CURL="curl"
CURL_OPTS=(-k --remote-name --silent --location-trusted)

# ----------------------------------------------------------------------------------------
# Logging functions
# ----------------------------------------------------------------------------------------
log()
{
  LOGFILE=${1}
  shift
  if [ -n "${CONSOLE_OUTPUT}" ]; then
      printf "%s ...\n" "${*}"
  fi
  {
    printf "\n-------------------------------------------------------\n"
    printf "  %s ...\n" "$*"
    printf "\n-------------------------------------------------------\n"
  } >> "${LOGFILE}"
}

log_done()
{
  if [ -n "${CONSOLE_OUTPUT}" ]; then
      printf \
      " done\n-------------------------------------------------------\n"
  fi
  {
    printf "\n-------------------------------------------------------\n"
    printf "  **DONE**\n"
    printf "\n-------------------------------------------------------\n"
  } >> "${1}"
}

error()
{
  if [ -n "${CONSOLE_OUTPUT}" ]; then
      printf "\nERROR: %s, exiting.\n" "$*" >&2
  fi
  printf "\nERROR: %s, exiting.\n" "$*" >> "$ACTUAL_LOGFILE"
  "$COMPRESSOR" -9f "$ACTUAL_LOGFILE"
  FILENAME="${CGAL_RELEASE_ID}-log$(date_str).gz"
  mv "${ACTUAL_LOGFILE}.gz" "$LOGS_DIR/$FILENAME"
  if [ ! "$MAIL_ADDRESS" = "must_be_set_in_.autocgalrc" ]; then
    for i in $MAIL_ADDRESS; do
      printf "ERROR\n%s\n" "$LOGS_DIR/$FILENAME" | \
          "$SENDMAIL" -s "completed autotest" "$i"
    done
  fi
  rm -rf "$LOCK_FILE"
  exit 1
}

# ----------------------------------------------------------------------------------------
# produce a string containing the actual date/time
#  (used to identify files)
# ----------------------------------------------------------------------------------------
date_str()
{
  date +%d%m%Y%H%M
}


# ----------------------------------------------------------------------------------------
# Downloads the file "LATEST" whose contents indicates which release to test
# ----------------------------------------------------------------------------------------
download_latest()
{
  if [ -r "LATEST" ]; then
    rm -rf LATEST
  fi
  log "$ACTUAL_LOGFILE" "getting LATEST"
  download_file "$LATEST_LOCATION" >> "$ACTUAL_LOGFILE" 2>&1
  if [ ! -f "LATEST" ]; then
    error "COULD NOT DOWNLOAD LATEST!"
  fi
}

# ----------------------------------------------------------------------------------------
# Exits the testsuite if the latest release has been already tested.
# This is tested by comparing files LATEST and RELEASE_NR, where
# RELEASE_NR is a copy of the previous LATEST.
# ----------------------------------------------------------------------------------------
abort_if_latest_already_tested()
{
  if [ -r "RELEASE_NR" ]; then
    if cmp LATEST RELEASE_NR >> "${ACTUAL_LOGFILE}"; then
      log "${ACTUAL_LOGFILE}" "This release has already been tested."
      rm -f "$LOCK_FILE";
      exit 1;
    fi
  fi
}



# ----------------------------------------------------------------------------------------
# get CGAL
# ----------------------------------------------------------------------------------------
get_cgal()
{
  if [ -z "$CGAL_LOCATION" ]; then
    while IFS= read -r i; do
      CGAL_LOCATION="${CGAL_URL}/$i"
      CGAL_ZIPFILE="$i"
    done < LATEST
  else
    CGAL_ZIPFILE="${CGAL_LOCATION##*/}"
  fi

  CGAL_RELEASE_ID="${CGAL_ZIPFILE%.tar.gz}"
  echo "$CGAL_RELEASE_ID" | tee last_release_id
  if [ "$CGAL_RELEASE_ID" != "$CGAL_ZIPFILE" ]; then
    USE_TARGZ="y"
  else
    CGAL_RELEASE_ID="${CGAL_ZIPFILE%.tar.bz2}"
    if [ "$CGAL_RELEASE_ID" != "$CGAL_ZIPFILE" ]; then
      USE_TARBZ="y"
    fi
  fi

  log "$ACTUAL_LOGFILE" "CGAL_ZIPFILE    = $CGAL_ZIPFILE"
  log "$ACTUAL_LOGFILE" "CGAL_RELEASE_ID = $CGAL_RELEASE_ID"

  log "$ACTUAL_LOGFILE" "getting CGAL"
  rm -f "$CGAL_ZIPFILE"
  if ! download_file "$CGAL_LOCATION" >> "$ACTUAL_LOGFILE" 2>&1; then
    error "Could not get CGAL"
  fi
  log_done "$ACTUAL_LOGFILE"
}


# ----------------------------------------------------------------------------------------
# Unzips and untars the downloaded CGAL release
# ----------------------------------------------------------------------------------------
unzip_cgal()
{
  cd "$CGAL_HOME" || exit

  log "$ACTUAL_LOGFILE" "unzipping CGAL"
  if [ "$USE_TARGZ" = "y" ]; then
    DECOMPRESSOR="$GUNZIP"
    log_done "$ACTUAL_LOGFILE"
  fi

  if [ "$USE_TARBZ" = "y" ]; then
    DECOMPRESSOR="bunzip2"
  fi

  log "$ACTUAL_LOGFILE" "untarring CGAL"
  if ! "$DECOMPRESSOR" -c "$CGAL_ZIPFILE" | "$TAR" xf - >> "$ACTUAL_LOGFILE" 2>&1; then
    error "Could not extract CGAL"
  fi

  # check, if CGAL_DIR exists
  if [ -d "$CGAL_HOME/$CGAL_RELEASE_ID" ]; then
    # Reset CGAL-I symlink
    log "$ACTUAL_LOGFILE" "Resetting CGAL-I symlink to $CGAL_HOME/$CGAL_RELEASE_ID"
    rm -f CGAL-I
    ln -s "$CGAL_HOME/$CGAL_RELEASE_ID" CGAL-I
    # Reset CGAL-3.x-I symlink
    CGAL_RELEASE="${CGAL_RELEASE_ID%%-*}"
    log "$ACTUAL_LOGFILE" "Resetting $CGAL_RELEASE symlink to $CGAL_HOME/$CGAL_RELEASE_ID"
    rm -f "$CGAL_RELEASE"
    ln -s "$CGAL_HOME/$CGAL_RELEASE_ID" "$CGAL_RELEASE"
  else
    error "directory $CGAL_HOME/$CGAL_RELEASE_ID does not exist"
  fi

  log_done "$ACTUAL_LOGFILE"
}



# Parse command line arguments
for arg in "$@"
do
  case "$arg" in
    "-c")
      echo "Using latest unzipped release instead of getting a new one from the server"
      USE_LATEST_UNZIPPED="y"
      ;;
    "-l")
      echo "Not uploading results to dashboard"
      DO_NOT_UPLOAD="y"
      ;;
    "-n")
       echo "No testsuite will be launched. Installation only."
      DO_NOT_TEST="y"
      ;;
    "-s")
      echo "Showing progress."
      SHOW_PROGRESS="y"
      ;;
    "-k")
      echo "Compiled test/ directory will be kept."
      KEEP_TESTS="y"
      ;;
    "-g")
      echo "Run testsuite from GIT branch"
      export INSTALLATION_DIR="Installation/"
      export TESTSUITE_DIR="Testsuite/"
      export SCRIPTS_DIR="Scripts/"
      UPLOAD_RESULT_DESTINATION="mgimeno@cgal.geometryfactory.com:incoming"
      ;;
    *)
      CGAL_LOCATION=$arg
  esac
done
# Load settings
if [ -f "${CGAL_HOME}/.autocgalrc" ]; then
  # shellcheck source=/dev/null
  . "${CGAL_HOME}/.autocgalrc"
else
  echo "CONFIGURATION FILE  .autocgalrc NOT FOUND" >&2;
  exit 1
fi

if [ -n "$USE_CURL" ]; then
  download_file() {
    "$CURL" "${CURL_OPTS[@]}" "$1"
  }
else
  download_file() {
    "$WGET" "${WGET_OPTS[@]}" "$1"
  }
fi

LOGS_DIR="${CGAL_HOME}/AUTOTEST_LOGS"
LOCK_FILE="${CGAL_HOME}/autotest_cgal_with_cmake.lock"

# Setup logfile
ACTUAL_LOGFILE="${CGAL_HOME}/$(basename "${0}").log"
rm -f "${ACTUAL_LOGFILE}"

echo "Running $(basename "${0}") \$Revision\$" >> "${ACTUAL_LOGFILE}"

cd "$CGAL_HOME" || exit

# Starts the process

if [ -z "${USE_LATEST_UNZIPPED}" ] && [ -z "${SCRIPTS_DIR}" ]; then
  if [ -z "$CGAL_LOCATION" ]; then
    download_latest
    abort_if_latest_already_tested
  fi
  get_cgal
  unzip_cgal
fi
#reset CGAL-DIR with the updated CGAL-I
if [ -n "${SCRIPTS_DIR}" ]; then
  CGAL_DIR=$(readlink "${CGAL_HOME}/CGAL-git")
else
  CGAL_DIR=$(readlink "${CGAL_HOME}/CGAL-I")
fi

CGAL_DIR=$(echo "$CGAL_DIR" | sed -E 's/\/cygdrive\/([a-z])\//\U\1:\//')

CGAL_RELEASE_ID=$(cat last_release_id)
for HOST in ${BUILD_HOSTS}; do
  HOST=$HOST bash -$- "${CGAL_DIR}/${SCRIPTS_DIR}developer_scripts/run_testsuite_with_ctest"
done

cd "${CGAL_HOME}" || exit
if [ -e "LATEST" ]; then
  mv LATEST RELEASE_NR
fi
