#!/bin/bash
# ----------------------------------------------------
# ----------------------------------------------------
# autotest_cgal: a script to automagically install and
#   test internal CGAL releases
# ----------------------------------------------------
# You will need
#  * GNU wget and ftp
#  * or alternatively curl
#
# Furthermore you have to edit .autocgalrc in order to
# customize it for your environment.
# In particular you have to change the BUILHOSTS
# variable to contain the names of your hosts and
# set the COMPILERS_<hostname> variables to the
# os-compilers descriptions on which you want to run
# the testsuite.
# ----------------------------------------------------
# ----------------------------------------------------
#
# $URL$
# $Id$

#sets the umask to 022 & 0777
umask 022

# Warn deprecated use of environment variables to pass on flags
if [ -n "$TESTSUITE_CXXFLAGS" ] ; then
  echo "\$TESTSUITE_CXXFLAGS is deprecated. Please use the CMAKE variable (CMAKE|CGAL)_CXX_FLAGS instead" >&2;
fi

if [ -n "$TESTSUITE_CXXFLAGS_RELEASE" ] ; then
  echo "\$TESTSUITE_CXXFLAGS_RELEASE is deprecated. Please use the CMAKE variable (CMAKE|CGAL)_CXX_FLAGS_RELEASE instead" >&2;
fi

if [ -n "$TESTSUITE_CXXFLAGS_DEBUG" ] ; then
  echo "\$TESTSUITE_CXXFLAGS_DEBUG is deprecated. Please use the CMAKE variable (CMAKE|CGAL)_CXX_FLAGS_DEBUG instead" >&2;
fi

if [ -n "$TESTSUITE_LDFLAGS" ] ; then
  echo "\$TESTSUITE_LDFLAGS is deprecated. Please use the CMAKE variable (CMAKE|CGAL)_(MODULE|SHARED|EXE)_LINKER_FLAGS instead" >&2;
fi

if [ -n "$TESTSUITE_LDFLAGS_RELEASE" ] ; then
  echo "\$TESTSUITE_LDFLAGS_RELEASE is deprecated. Please use the CMAKE variable (CMAKE|CGAL)_(MODULE|SHARED|EXE)_LINKER_FLAGS_RELEASE instead" >&2;
fi

if [ -n "$TESTSUITE_LDFLAGS_DEBUG" ] ; then
  echo "\$TESTSUITE_LDFLAGS_DEBUG is deprecated. Please use the CMAKE variable (CMAKE|CGAL)_(MODULE|SHARED|EXE)_LINKER_FLAGS_DEBUG instead" >&2;
fi

# We want english warning and error messages!!
LANG=C
LC_ALL=C
export LANG
export LC_ALL

SCP="scp"
WGET="wget"
WGET_OPTS="--no-check-certificate --no-verbose"
CURL="curl"
CURL_OPTS="-k --remote-name --silent --location-trusted"
CGAL_URL="https://cgal.geometryfactory.com/CGAL/Releases"
LATEST_LOCATION="${CGAL_URL}/LATEST"
TAR="tar"
GZIP="gzip"
GUNZIP="gunzip"
COMPRESSOR="${GZIP}"
SENDMAIL="mail"
CGAL_TESTER=`whoami`
CGAL_TESTER_NAME="${CGAL_TESTER}"
CGAL_TESTER_ADDRESS="${CGAL_TESTER}"
CONSOLE_OUTPUT="y"
CGAL_ROOT=`pwd`
UPLOAD_RESULT_DESTINATION="cgaltest@cgaltest.geometryfactory.com:incoming"
BUILD_HOSTS="must_be_set_in_.autocgalrc"
MAIL_ADDRESS="must_be_set_in_.autocgalrc"
MYSHELL=""
REFERENCE_PLATFORMS_DIR="must_be_set_in_.autocgalrc"
ACTUAL_DIR=`pwd`
RSH="rsh"
NICE_OPTIONS="-19"
USE_TARGZ="n"
USE_TARBZ="n"
PLATFORMS=""
PLATFORM=""
USE_REFERENCE_PLATFORMS=""
SHOW_PROGRESS=""

# ----------------------------------------------------------------------------------------
# write to logfile
# $1 = logfile
# ----------------------------------------------------------------------------------------
log()
{
  LOGFILE=${1}
  shift
  if [ -n "${CONSOLE_OUTPUT}" ]; then
      printf "${*} ...\n"
  fi
  printf "\n-------------------------------------------------------\n" >> "${LOGFILE}"
  printf "  ${*} ...\n"                                                >> "${LOGFILE}"
  printf "\n-------------------------------------------------------\n" >> "${LOGFILE}"
}

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

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

# ----------------------------------------------------------------------------------------
# Print error and exit
# ----------------------------------------------------------------------------------------
error()
{
  if [ -n "${CONSOLE_OUTPUT}" ]; then
      printf "\nERROR: ${*}, exiting.\n" >&2
  fi
  printf "\nERROR: ${*}, exiting.\n" >> "${ACTUAL_LOGFILE}"
  ${COMPRESSOR} -9f "${ACTUAL_LOGFILE}"
  FILENAME="${CGAL_RELEASE_ID}-log`datestr`.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${LOGS_DIR}/${FILENAME}\n" | \
          ${SENDMAIL} -s "completed autotest" "${i}"
    done
  fi
  rm -rf "$LOCK_FILE";
  exit 1
}

# ----------------------------------------------------------------------------------------
# Return 0 if $1 exists in the list $2, otherwise returns non-zero.
# ----------------------------------------------------------------------------------------
is_in_list()
{
  ELEMENT=${1}
  LIST=${2}

  for E in ${LIST} ; do
    if [ "${E}" = "${ELEMENT}" ] ; then
      return 0
    fi
  done

  return 1
}

# ----------------------------------------------------------------------------------------
# function to print the value of variable $1
# ----------------------------------------------------------------------------------------
value_of()
{
  _value=`eval "printf '$'${1}"`
  eval "printf \"${_value}\""
}

# ----------------------------------------------------------------------------------------
# Executes a command remotely
# $1 = HOST
# $2 = COMMAND
# ----------------------------------------------------------------------------------------
remote_command()
{
  if [ "${1}" = "localhost" ]; then
      eval $2
  else
    printf "** Logging into host ${1} **\n"
    ${RSH} ${1} ${MYSHELL} \"${2}\"
  fi
}

# ----------------------------------------------------------------------------------------
# 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"
    if [ -n "${USE_CURL}" ]; then
      ${CURL} ${CURL_OPTS} "${LATEST_LOCATION}" >> "${ACTUAL_LOGFILE}" 2>&1
    else
      ${WGET} ${WGET_OPTS} "${LATEST_LOCATION}" >> "${ACTUAL_LOGFILE}" 2>&1
    fi
  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
    cmp LATEST RELEASE_NR >> "${ACTUAL_LOGFILE}"
    if [ ! ${?} != 0 ]; 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
    for i in `cat LATEST`
    do
      CGAL_LOCATION="${CGAL_URL}/${i}";
      CGAL_ZIPFILE="${i}";
    done
  else
    CGAL_ZIPFILE=`echo "$CGAL_LOCATION" | sed 's|.*/||'`
  fi

  CGAL_RELEASE_ID=`echo $CGAL_ZIPFILE | sed "s/.tar.gz//"`
  if [ ! "${CGAL_RELEASE_ID}" = "${CGAL_ZIPFILE}" ]; then
    USE_TARGZ="y"
  else
    CGAL_RELEASE_ID=`echo $CGAL_ZIPFILE | sed "s/.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 [ -n "${USE_CURL}" ]; then
      ${CURL} ${CURL_OPTS} "${CGAL_LOCATION}" >> "${ACTUAL_LOGFILE}" 2>&1
  else
      ${WGET} ${WGET_OPTS} "${CGAL_LOCATION}" >> "${ACTUAL_LOGFILE}" 2>&1
  fi
  if [ ${?} != 0 ]; then
    error "Could not get CGAL"
  fi
  log_done "${ACTUAL_LOGFILE}"
}


# ----------------------------------------------------------------------------------------
# Unzips and untars the downloaded CGAL release
# ----------------------------------------------------------------------------------------
unzip_cgal()
{
  cd "${CGAL_ROOT}"

  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"
  ${DECOMPRESSOR} -c "${CGAL_ZIPFILE}" | ${TAR} xf - >> "${ACTUAL_LOGFILE}" 2>&1
  if [ ${?} != 0 ]; then
    error "Could not untar CGAL"
  fi

  # check, if CGAL_DIR exists
  if [ -d "${CGAL_ROOT}/${CGAL_RELEASE_ID}" ]; then
    # Reset CGAL-I symlink
    log "${ACTUAL_LOGFILE}" "Resetting CGAL-I symlink to ${CGAL_ROOT}/${CGAL_RELEASE_ID}"
    rm -f CGAL-I
    ln -s "${CGAL_ROOT}/${CGAL_RELEASE_ID}" CGAL-I
    # Reset CGAL-3.x-I symlink
    CGAL_RELEASE=`echo "${CGAL_RELEASE_ID}" | sed 's/I\([^-]*\)-.*/I\1/'`
    log "${ACTUAL_LOGFILE}" "Resetting ${CGAL_RELEASE} symlink to ${CGAL_ROOT}/${CGAL_RELEASE_ID}"
    rm -f "${CGAL_RELEASE}"
    ln -s "${CGAL_ROOT}/${CGAL_RELEASE_ID}" "${CGAL_RELEASE}"
  else
    error "directory ${CGAL_ROOT}/${CGAL_RELEASE_ID} does not exist"
  fi

  log_done "${ACTUAL_LOGFILE}"
}


# ----------------------------------------------------------------------------------------
# Uniquely adds $1 to the global, space-separated list $PLATFORMS
# (if it is not in the list already)
# ----------------------------------------------------------------------------------------
add_to_platforms()
{
  if ! is_in_list "${1}" "${PLATFORMS}" ; then
    PLATFORMS="${PLATFORMS} ${1}"
  fi
}

# ----------------------------------------------------------------------------------------
# Uniquely adds to the global, space-separated list $PLATFORMS all the directories found
# under ${REFERENCE_PLATFORMS_DIR}
# ----------------------------------------------------------------------------------------
collect_all_reference_platforms()
{
  log "${ACTUAL_LOGFILE}" "Indicated to build on ALL platform folders"
  if [ -d "${REFERENCE_PLATFORMS_DIR}" ]; then
    cd "${REFERENCE_PLATFORMS_DIR}"
    for PLATFORM in * ; do
      if [ -d "${PLATFORM}" ]; then
        add_to_platforms "${PLATFORM}"
      fi
    done
  else
    log "${ACTUAL_LOGFILE}" "WARNING: Invalid reference platforms directory: ${REFERENCE_PLATFORMS_DIR}"
  fi
}

# ----------------------------------------------------------------------------------------
# Uniquely adds to the global, space-separated list $PLATFORMS all the directories found
# under $1
# ----------------------------------------------------------------------------------------
collect_all_current_platforms()
{
  PLATFORMS=""
  cd "${1}"
  for PLATFORM in * ; do
    if [ -d "${PLATFORM}" ]; then
      PLATFORMS="${PLATFORMS} ${PLATFORM}"
    fi
  done
}

# ----------------------------------------------------------------------------------------
# Uniquely adds to the global, space-separated list $PLATFORMS all the directory names
# listed in the space-separated list $1
# NOTE: If any such name is "all", it's NOT added as a platform and the flag
# USE_REFERENCE_PLATFORMS is set instead.
# ----------------------------------------------------------------------------------------
build_platforms_list()
{
  for LOCAL_PLATFORM in $1; do
    if [ "${LOCAL_PLATFORM}" = "all" ] ; then
      USE_REFERENCE_PLATFORMS='y'
    else
      add_to_platforms "${LOCAL_PLATFORM}"
    fi
  done
}

# ----------------------------------------------------------------------------------------
# Sets up the variables indicating the directories to use.
# Crates all platform directories under the current release binary folder.
# ----------------------------------------------------------------------------------------
setup_dirs()
{
  # dir for the actual release
  CGAL_DIR=`readlink "${CGAL_ROOT}/CGAL-I"`

  CGAL_TEST_DIR=${CGAL_DIR}/test
  CGAL_DATA_DIR=${CGAL_DIR}/data
  export CGAL_DATA_DIR=$(echo "$CGAL_DATA_DIR" | sed -E 's/\/cygdrive\/([a-z])\//\U\1:\//')

  if [ ! -d "${CGAL_DIR}/cmake" ]; then
    mkdir "${CGAL_DIR}/cmake"
    log "${ACTUAL_LOGFILE}" "Creating ${CGAL_DIR}/cmake"
  fi

  if [ ! -d "${CGAL_DIR}/cmake/platforms" ]; then
    mkdir "${CGAL_DIR}/cmake/platforms"
    log "${ACTUAL_LOGFILE}" "Creating ${CGAL_DIR}/cmake/platforms"
  fi

  export CGAL_RELEASE_DIR="${CGAL_DIR}"

  CGAL_RELEASE_ID=`basename "${CGAL_RELEASE_DIR}"`

  CGAL_BINARY_DIR_BASE=${CGAL_RELEASE_DIR}/cmake/platforms

  log "${ACTUAL_LOGFILE}" "Release to test ${CGAL_RELEASE_DIR}"
  log "${ACTUAL_LOGFILE}" "CGAL_RELEASE_ID=${CGAL_RELEASE_ID}"

  if [ ! -r "${LOGS_DIR}" ]; then
    mkdir "$LOGS_DIR"
  fi

  #
  # Collects the list of platform directories to build and test on
  #
  # The global variable PLATFORMS contains all the platform directories for all hosts
  # as indicated in .autocgalrc.
  # If .autocgalrc says "all" in any entry for BUILD_ON_* or COMPILERS_*, the platform
  # directories existing in the reference release are added to $PLATFORMS
  #
  PLATFORMS=""

  for HOST in ${BUILD_HOSTS}; do

    build_platforms_list "`value_of BUILD_ON_${HOST}`"
    build_platforms_list "`value_of COMPILERS_${HOST}`"

  done

  if [ -n "${USE_REFERENCE_PLATFORMS}" ]; then
    collect_all_reference_platforms
  fi


  for PLATFORM in ${PLATFORMS}; do

    # MSVC2015 does not support C++17
    if [ "$CGAL_RELEASE_ID" \> "CGAL-6.0" ]; then
      if [ "$PLATFORMS" = "MSVC2015-Release-64bits" ]; then
        continue
      fi
    fi

    CGAL_BINARY_DIR=${CGAL_BINARY_DIR_BASE}/${PLATFORM}

    if [ ! -d "${CGAL_BINARY_DIR}" ]; then
      log "${ACTUAL_LOGFILE}" "Creating platform directory ${CGAL_BINARY_DIR}"
      mkdir "${CGAL_BINARY_DIR}"
    fi

  done
}


# ----------------------------------------------------------------------------------------
# copy stuff from old CGAL installation
# ----------------------------------------------------------------------------------------
copy_old_stuff()
{
  if [ -d "${REFERENCE_PLATFORMS_DIR}" ]; then

    cd "${CGAL_BINARY_DIR_BASE}"

    for PLATFORM in * ; do
      if [ -d "${PLATFORM}" ]; then

        # if the reference platform folder contains a setup script, copy it
        if [ -f "${REFERENCE_PLATFORMS_DIR}/${PLATFORM}/setup" ]; then
          log "${ACTUAL_LOGFILE}" "Copying reference platform setup script [${REFERENCE_PLATFORMS_DIR}/${PLATFORM}/setup] in [${CGAL_BINARY_DIR_BASE}/${PLATFORM}]"
          cp "${REFERENCE_PLATFORMS_DIR}/${PLATFORM}/setup" "${CGAL_BINARY_DIR_BASE}/${PLATFORM}"

          # hack on Windows, where 'cp' does not copy the Windows ACLs
          chmod a+r "${CGAL_BINARY_DIR_BASE}/${PLATFORM}/setup"
        fi
      fi
    done

  fi
}


# ----------------------------------------------------------------------------------------
# Builds the CGAL library on the host specified at $1
# ----------------------------------------------------------------------------------------
build_cgal_on_host()
{
  HOST=${1}

  PLATFORMS="`value_of BUILD_ON_${HOST}`"


  if [ -z "${PLATFORMS}" ]; then
    PLATFORMS=`value_of COMPILERS_${HOST}`
  fi

  if [ "${PLATFORMS}" = "all" ]; then
    collect_all_current_platforms "${CGAL_BINARY_DIR_BASE}"
  fi

  if [ -n "${PLATFORMS}" ]; then

    for PLATFORM in ${PLATFORMS} ; do

      CGAL_BINARY_DIR="${CGAL_BINARY_DIR_BASE}/${PLATFORM}"

      log "${ACTUAL_LOGFILE}" "Building cgal libs on host ${HOST} and platform ${PLATFORM}\nUnder ${CGAL_BINARY_DIR}\n"

      if [ -f "${CGAL_BINARY_DIR}/localbuildscript" ] ; then
        log "${ACTUAL_LOGFILE}" "WARNING! Already built on platform ${PLATFORM}."
      else

        if [ -f "${CGAL_BINARY_DIR}/setup" ]; then
          cp "${CGAL_BINARY_DIR}/setup" "${CGAL_BINARY_DIR}/localbuildscript"
        else
          rm -f "${CGAL_BINARY_DIR}/localbuildscript"
        fi

        cat >> "${CGAL_BINARY_DIR}/localbuildscript" <<EOF
CGAL_BINARY_DIR='${CGAL_BINARY_DIR}';
MAKE_CMD='${MAKE_CMD}';

export MAKE_CMD;
export CGAL_BINARY_DIR;
cd '${CGAL_BINARY_DIR}';
cmake \${INIT_FILE:+"-C\${INIT_FILE}"} -DRUNNING_CGAL_AUTO_TEST=TRUE \\
                           VERBOSE=1 \\
                           ../../..;
${MAKE_CMD} VERBOSE=ON -k -fMakefile  ;
cd ..;
EOF
        if [ -z "${KEEP_TESTS}" ]; then
          cat >> "${CGAL_BINARY_DIR}/localbuildscript" <<EOF
echo 'REMOVING COMPILATION TREE';
rm -rf '${CGAL_BINARY_DIR}/src'
EOF
        fi
        chmod ugo+x "${CGAL_BINARY_DIR}/localbuildscript"
        if [ -n "${SHOW_PROGRESS}" ]; then
          remote_command ${HOST} "${CGAL_BINARY_DIR}/localbuildscript"  2>&1 | tee "${ACTUAL_LOGFILE}.build.${PLATFORM}"
        else
          remote_command ${HOST} "${CGAL_BINARY_DIR}/localbuildscript" > "${ACTUAL_LOGFILE}.build.${PLATFORM}" 2>&1
        fi

        cp "${ACTUAL_LOGFILE}.build.${PLATFORM}" "${CGAL_BINARY_DIR}/installation.log"
      fi

    done
  else
    error "There are no platform directories under ${CGAL_BINARY_DIR_BASE} to test! "
  fi

}


# ----------------------------------------------------------------------------------------
# builds cgal
# ----------------------------------------------------------------------------------------
build_cgal()
{
  for HOST in ${BUILD_HOSTS}; do
      build_cgal_on_host "${HOST}"
  done

  # NOTE: At this point PWD is in the last platform directory where CGAL was built

  log_done "${ACTUAL_LOGFILE}"
  cp "${ACTUAL_LOGFILE}" "${CGAL_BINARY_DIR_BASE}/installation.log"
  ${COMPRESSOR} -9f "${ACTUAL_LOGFILE}"
  mv "${ACTUAL_LOGFILE}.gz" "${LOGS_DIR}/${CGAL_RELEASE_ID}-log`datestr`.gz"
}

# ----------------------------------------------------------------------------------------
# Runs the test on the host $1 under the platform folder $2
# the variable PROCESSORS_electra, where electra is the
# name of the machine, is used to specify the number of
# processors to use
# ----------------------------------------------------------------------------------------
run_test_on_host_and_platform()
{
  HOST=${1}
  PLATFORM=${2}

  NUMBER_OF_PROCESSORS="`value_of PROCESSORS_${HOST}`"
  CGAL_BINARY_DIR=${CGAL_BINARY_DIR_BASE}/${PLATFORM}
  cd "${CGAL_BINARY_DIR}"
  log "${ACTUAL_LOGFILE}.test.${PLATFORM}" "Testing on host ${HOST} and platform ${PLATFORM}"
  if [ "${NUMBER_OF_PROCESSORS}" = "1" ] ; then
    MAKE_OPTS=""
  else
    MAKE_OPTS="-j ${NUMBER_OF_PROCESSORS}"
  fi

  if [ -f "${CGAL_BINARY_DIR}/localtestscript" ]; then
    log "${ACTUAL_LOGFILE}" "WARNING! Already tested on platform ${PLATFORM}."
  else
    if [ -f "${CGAL_BINARY_DIR}/setup" ]; then
      cp "${CGAL_BINARY_DIR}/setup" "${CGAL_BINARY_DIR}/localtestscript"
    else
      rm -f "${CGAL_BINARY_DIR}/localtestscript"
    fi

    for file in "${CGAL_BINARY_DIR}/localtestscript" "${CGAL_BINARY_DIR}/localtestscript-redo-results-collection"; do
      cat >> "$file" <<EOF
CGAL_TESTER='${CGAL_TESTER}';
CGAL_TESTER_NAME='${CGAL_TESTER_NAME}';
CGAL_TESTER_ADDRESS='${CGAL_TESTER_ADDRESS}';
if [ -n "${IS_CYGWIN}" ]; then
  CGAL_DIR=\$( cygpath -w "${CGAL_BINARY_DIR}" );
else
  CGAL_DIR='${CGAL_BINARY_DIR}';
fi
CGAL_TEST_HOST='${HOST}';
CGAL_TEST_PLATFORM='${PLATFORM}';
MAKE_CMD='${MAKE_CMD}'
export CGAL_TESTER CGAL_TESTER_NAME CGAL_TESTER_ADDRESS;
export CGAL_DIR;
export CGAL_TEST_HOST CGAL_TEST_PLATFORM;
export MAKE_CMD;

EOF
    done
    cat >> "${CGAL_BINARY_DIR}/localtestscript" <<EOF
LIST_TEST_PACKAGES='${LIST_TEST_PACKAGES}'
CGAL_ROOT='${CGAL_ROOT}'

rm -rf '${CGAL_BINARY_DIR}/test';
if [ -f '${LIST_TEST_PACKAGES}' ]; then
  mkdir '${CGAL_BINARY_DIR}/test'

  cp '${CGAL_TEST_DIR}/collect_cgal_testresults_from_cmake' '${CGAL_BINARY_DIR}/test'
  cp '${CGAL_TEST_DIR}/makefile2'                           '${CGAL_BINARY_DIR}/test'
  cp '${CGAL_TEST_DIR}/run_testsuite_with_cmake'            '${CGAL_BINARY_DIR}/test'

  # list all packages in CGAL_TEST_DIR. If PACKAGE is found in LIST_TEST_PACKAGES,
  # copy it, else prepare for the special "skipped" case in the table.
  for PACKAGE in \$(ls "${CGAL_TEST_DIR}"); do
    if [ -d "${CGAL_TEST_DIR}/\$PACKAGE" ]; then
      if source '${LIST_TEST_PACKAGES}' '${CGAL_ROOT}' | grep -E -q \$PACKAGE; then
        mkdir "${CGAL_BINARY_DIR}/test/\${PACKAGE}"
        cp -r "${CGAL_TEST_DIR}/\${PACKAGE}" '${CGAL_BINARY_DIR}/test'
      elif [ "\$PACKAGE" = "resources" ]; then
        mkdir "${CGAL_BINARY_DIR}/test/\${PACKAGE}"
        cp -r "${CGAL_TEST_DIR}/\${PACKAGE}" '${CGAL_BINARY_DIR}/test'
      else
        mkdir "${CGAL_BINARY_DIR}/test/\${PACKAGE}"
        touch "${CGAL_BINARY_DIR}/test/\${PACKAGE}/skipped"
      fi
    fi

  done

else
  cp -r '${CGAL_TEST_DIR}' '${CGAL_BINARY_DIR}/test';
fi

cd '${CGAL_BINARY_DIR}/test';
if [ -n "\${ULIMIT_OPTIONS}" ]; then
  eval ulimit \${ULIMIT_OPTIONS};
else
  [ -n "${ULIMIT_OPTIONS}" ] && ulimit ${ULIMIT_OPTIONS};
fi
nice ${NICE_OPTIONS} make ${MAKE_OPTS} -k -fmakefile2;
EOF
    for file in "${CGAL_BINARY_DIR}/localtestscript" "${CGAL_BINARY_DIR}/localtestscript-redo-results-collection"; do
      cat >> "$file" <<EOF
echo 'COLLECTING RESULTS';
./collect_cgal_testresults_from_cmake;
if [ -n "\$COLLECT_DEMOS_BINARIES" ]; then
  echo 'COLLECTING DEMOS BINARIES';
  echo "cp ${CGAL_TEST_DIR}/../developer_scripts/cgal_demo_copy_all_dlls_cygwin.sh ${CGAL_BINARY_DIR}/test"
  cp "${CGAL_TEST_DIR}/../developer_scripts/cgal_demo_copy_all_dlls_cygwin.sh" "${CGAL_BINARY_DIR}/test"
EOF
  cat >> "$file" <<'EOF'
  for demo_dir in *_Demo; do
    echo "pushd ${demo_dir}"
    pushd "${demo_dir}"
    bash ../cgal_demo_copy_all_dlls_cygwin.sh "${demo_dir}_with_dlls" ""
    mv "${demo_dir}_with_dlls" ..
    popd
  done
EOF
cat >> "$file" <<EOF
  tar czvf "${CGAL_TEST_DIR}/demos_${CGAL_TESTER}_${PLATFORM}.tar.gz" *_Demo_with_dlls/*
fi
echo 'COPYING RESULTS';
cp 'results_${CGAL_TESTER}_${PLATFORM}.tar.gz' 'results_${CGAL_TESTER}_${PLATFORM}.txt' '${CGAL_TEST_DIR}';
cd ..;
EOF
    done
    if [ -z "${KEEP_TESTS}" ]; then
      cat >> "${CGAL_BINARY_DIR}/localtestscript" <<EOF
echo 'REMOVING LOCAL_TEST_DIR';
rm -rf '${CGAL_BINARY_DIR}/test'
EOF
    fi


    chmod ugo+x "${CGAL_BINARY_DIR}"/localtestscript*

    if [ -n "${SHOW_PROGRESS}" ]; then
      remote_command ${HOST} "${CGAL_BINARY_DIR}/localtestscript" 2>&1 | tee "${ACTUAL_LOGFILE}.test.${PLATFORM}"
    else
      remote_command ${HOST} "${CGAL_BINARY_DIR}/localtestscript" > "${ACTUAL_LOGFILE}.test.${PLATFORM}" 2>&1
    fi

    log_done "${ACTUAL_LOGFILE}.test.${PLATFORM}"

  fi
}

publish_results()
{
  HOST=${1}
  PLATFORM=${2}

  #
  # collect results and put them on the web
  #
  cd "${CGAL_TEST_DIR}"

  log "${ACTUAL_LOGFILE}.test.${PLATFORM}" "COLLECTING RESULTS ${PLATFORM}-${HOST}"

  # If this file does not exist results collection failed. Fake a results so this fact is itself reported
  if [ ! -f "results_${CGAL_TESTER}_${PLATFORM}.txt" ]; then
    log "${ACTUAL_LOGFILE}.test.${PLATFORM}" "Results collection for tester ${CGAL_TESTER} and platform ${PLATFORM} failed!"
    echo "Results collection failed!" >> "results_${CGAL_TESTER}_${PLATFORM}.txt"
    ${TAR} cf "results_${CGAL_TESTER}_${PLATFORM}.tar" "results_${CGAL_TESTER}_${PLATFORM}.txt"
    ${COMPRESSOR} -9f "results_${CGAL_TESTER}_${PLATFORM}.tar"
  fi

  ${TAR} cf "test_results-${HOST}_${PLATFORM}.tar" "results_${CGAL_TESTER}_${PLATFORM}.tar.gz" "results_${CGAL_TESTER}_${PLATFORM}.txt"
  ${COMPRESSOR} -9f "test_results-${HOST}_${PLATFORM}.tar"
  COMPILER=`printf "%s" "$2" | tr -c '[A-Za-z0-9]./[=-=]*_\'\''\":?() ' 'x'`
  FILENAME="${CGAL_RELEASE_ID}_${CGAL_TESTER}-test`datestr`-${COMPILER}-cmake.tar.gz"
  LOGFILENAME="${CGAL_RELEASE_ID}-log`datestr`-${HOST}.gz"
  ${COMPRESSOR} -9f "${ACTUAL_LOGFILE}.test.${PLATFORM}"
  mv "${ACTUAL_LOGFILE}.test.${PLATFORM}.gz" "${LOGS_DIR}/${LOGFILENAME}"

  log_done "${ACTUAL_LOGFILE}.test.${PLATFORM}"

  log "${ACTUAL_LOGFILE}" "Test results: ${CGAL_TEST_DIR}/test_results-${HOST}_${PLATFORM}.tar.gz"

  if [ -z "${DO_NOT_UPLOAD}" ]; then
    log "${ACTUAL_LOGFILE}.test.${PLATFORM}" "PUTTING RESULTS ON THE WEB"
    put_on_web "test_results-${HOST}_${PLATFORM}.tar.gz" "${FILENAME}"
    if [ -e "demos_${CGAL_TESTER}_${PLATFORM}.tar.gz" ]; then
      put_on_web "demos_${CGAL_TESTER}_${PLATFORM}.tar.gz" "demos-${FILENAME}"
    fi
    log_done "${ACTUAL_LOGFILE}"
  fi

  #
  # notify the CGAL world
  #
  if [ ! "${MAIL_ADDRESS}" = "must_be_set_in_.autocgalrc" ]; then
    for i in ${MAIL_ADDRESS}; do
      echo "Notifying ${i} about autotest finished."
      printf "result collection::\n${FILENAME}\n" | ${SENDMAIL} -s "autohandle" ${i}
    done
  fi
}

# ----------------------------------------------------------------------------------------
# Runs the test on the host $1
# ----------------------------------------------------------------------------------------
run_test_on_host()
{
  HOST=${1}

  PLATFORMS=`value_of COMPILERS_${HOST}`

  if [ "${PLATFORMS}" = "all" ]; then
    collect_all_current_platforms "${CGAL_BINARY_DIR_BASE}"
  fi

  for PLATFORM in ${PLATFORMS}; do
    run_test_on_host_and_platform "${HOST}" "${PLATFORM}"
    publish_results "${HOST}" "${PLATFORM}"
  done
}

# ----------------------------------------------------------------------------------------
# run the testsuites
# ----------------------------------------------------------------------------------------
run_test()
{
  log "${ACTUAL_LOGFILE}" "running the testsuites"
  if [ -n "${CONSOLE_OUTPUT}" ]; then
      printf "\n-------------------------------------------------------\n"
  fi

  for HOST in ${BUILD_HOSTS}; do
    run_test_on_host ${HOST} &
  done
}

# ----------------------------------------------------------------------------------------
# function to put result files on the web
# $1 = source filename (full path)
# $2 = target filename (basename only)
# ----------------------------------------------------------------------------------------
put_on_web()
{
  log "${ACTUAL_LOGFILE}" "Uploading results ${1} to $UPLOAD_RESULT_DESTINATION/$2"

  "$SCP" "${1}" "$UPLOAD_RESULT_DESTINATION/$2" >> "${ACTUAL_LOGFILE}"
}




# ----------------------------------------------------
# START OF MAIN BODY
# ----------------------------------------------------

# 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"
      ;;
    *)
      CGAL_LOCATION=$arg
  esac
done

# Load settings
if [ -f "$HOME/.autocgal_with_cmake_rc" ]; then
  . "$HOME/.autocgal_with_cmake_rc"
else
  if [ -f "$HOME/.autocgalrc" ]; then
    . "$HOME/.autocgalrc"
  else
    echo "CONFIGURATION FILE .autocgal_with_cmake_rc or .autocgalrc NOT FOUND" >&2;
    exit 1
  fi
fi

LOGS_DIR="${CGAL_ROOT}/AUTOTEST_LOGS"
LOCK_FILE="${CGAL_ROOT}/autotest_cgal_with_cmake.lock"
LIST_TEST_PACKAGES="${CGAL_ROOT}/list_test_packages"

# Setup logfile
ACTUAL_LOGFILE="${CGAL_ROOT}/`basename ${0}`.log"
rm -f "${ACTUAL_LOGFILE}"

echo "Running `basename ${0}` "'$Revision$' >> "${ACTUAL_LOGFILE}"

# Sanity checks
if [ "${REFERENCE_PLATFORMS_DIR}" = "must_be_set_in_.autocgalrc" ]; then
  error "REFERENCE_PLATFORMS_DIR must be set in .autocaglrc"
fi

if [ "${BUILD_HOSTS}" = "must_be_set_in_.autocgalrc" ]; then
  error "BUILD_HOSTS must be set in .autocgalrc"
else
  for i in ${BUILD_HOSTS}; do
    TEXT="`value_of COMPILERS_${i}`"
    if [ -z "${TEXT}" -a "${i}" != "localhost" ]; then
      error "COMPILERS_${i} must be defined in .autocgalrc"
    else
      TEXT="`value_of PROCESSORS_${i}`"
      TEMPVAR="PROCESSORS_${i}"
      if [ -z "${TEXT}" ]; then
        log "${ACTUAL_LOGFILE}" "\ngiving default 1 values TO PROCESSORS_${i} ...";
        eval $TEMPVAR="1";
      fi
    fi
  done
fi

# Make that file writable (lockfile create read-only files
chmod u+w "$LOCK_FILE"
# Put the PID of current process in the lock file
echo $$ > "$LOCK_FILE"

fi

# that line makes the script remove the lock file in case of unwanted exit
trap "rm -f \"$LOCK_FILE\"" EXIT HUP INT TERM

# Notify test started
if [ ! "${MAIL_ADDRESS}" = "must_be_set_in_.autocgalrc" ]; then
  for i in ${MAIL_ADDRESS}; do
    echo "Notifying ${i} about autotest started."
    printf "subject says it all\n" | \
        ${SENDMAIL} -s "Started autotest" ${i}
  done
fi



cd "$CGAL_ROOT"

# Starts the process

if [ -z "${USE_LATEST_UNZIPPED}" ]; then
  if [ -z "$CGAL_LOCATION" ]; then
    download_latest
    abort_if_latest_already_tested
  fi
  get_cgal
  unzip_cgal
fi

setup_dirs

copy_old_stuff

build_cgal

if [ "${BUILD_HOSTS}" = "localhost" ]; then
  TEXT="`value_of COMPILERS_localhost`"
  if [ -z "${DO_NOT_TEST}" ]; then
    if [ -z "${TEXT}" ]; then
      printf "Skipping testing phase (use the -n option to remove this message).\n"
      DO_NOT_TEST="y"
    fi
  fi
fi

if [ -z "${DO_NOT_TEST}" ]; then
  run_test
fi

cd "${CGAL_ROOT}"

if [ -e "LATEST" ]; then
  mv LATEST RELEASE_NR
fi

rm -f "$LOCK_FILE";

# EOF

## Local Variables:
## sh-basic-offset: 2
## End:
