#!/bin/sh

#----------------------------------------------------------------------------
# Automated build and test for SCST.  Compares SCST build from 24 hours
# ago with the current one.  See the README.txt on how to run it.
#----------------------------------------------------------------------------


#----------------------------------------------------------------------------
# Helper functions
#----------------------------------------------------------------------------

# Returns the revision number of the source files with date $1.
get_revision() {
  if svn info . >/dev/null 2>&1; then
    svn info -r "{$1}" "${scst_repo}" | sed -n 's/^Revision: //p'
  else
    git log --before="$1" | head -n 1 | cut -f2 -d ' '
  fi
}

runcmd () {
   logfile="$1"
   str="$2"
   shift 2

   # Header in short logfile
   printf "%-30s ..." "$str" >> ${logfile}.short

   # Header and command in verbose logfile
   { printf "%-30s ... " "$str"; echo "$*"; } >> ${logfile}.verbose

   # Run the command
   ("${ABT_EVAL}" "$*") >> ${logfile}.verbose 2>&1
   res=$?

   # Write result to the short logfile
   if [ $res = 0 ]
   then
      echo "done"   >> ${logfile}.short
   else
      echo "failed" >> ${logfile}.short
   fi

   return $res
}

usage () {
    echo "usage: $0 [-r <recipient>] <tag>"
}

#----------------------------------------------------------------------------
# Startup
#----------------------------------------------------------------------------

scst_rootdir="$(dirname "$(dirname "$(cd "$(dirname "$0")" && echo "$PWD")")")"
if svn info . >/dev/null 2>&1; then
  scst_repo="$(svn info "$scst_rootdir" | sed -n -e 's|\+ssh://[^@]*@|://|' -e 's/^URL: //p')"
else
  scst_repo="$scst_rootdir"
fi
sendmail_opts=""
run_if_unchanged="false"

set -- $(/usr/bin/getopt "ahr:" "$@")
while [ "$1" != "${1#-}" ]
do
  case "$1" in
    '-a') run_if_unchanged=true; shift;;
    '-h') usage; exit 1;;
    '-r') sendmail_opts="$1 $2"; shift; shift;;
    '--') shift;;
    *)    usage; exit 1;;
  esac
done

# Must have exactly one argument
if [ "$#" -ne 1 ] ; then
    usage
    exit 1
fi

# Get args from command line
if [ "${arg0#/}" = "${arg0}" ]; then
  scriptpath=`dirname $PWD/$0`
else
  scriptpath=`dirname $0`
fi
ABT_TOP=`dirname ${scriptpath}`
ABT_MACHINE="$1"

# Get times and date
ABT_START=`date "+%F %H:%M:%S %Z"`

old_date=`date --date=yesterday +%Y-%m-%dT%H:%M:%S`
new_date=`date --date=today     +%Y-%m-%dT%H:%M:%S`

cd $ABT_TOP

# Clean up output files produced by a previous run.
rm -rf diffs diff.short final new.short new.verbose old.short old.verbose
rm -rf sendmail.log unchanged.log

# Setup any relevant environment variables from conf/<tag>.conf.
. conf/$ABT_MACHINE.conf
if [ "${ABT_JOBS}" = "" ]; then
  ABT_JOBS=1
fi
if [ "${ABT_EVAL}" = "" ]; then
  ABT_EVAL="eval"
fi
if [ "${ABT_TMPDIR}" = "" ]; then
  ABT_TMPDIR="/tmp/scst-$$"
fi


#----------------------------------------------------------------------------
# Check out, build, test
#----------------------------------------------------------------------------

old_rev="`get_revision ${old_date}`"
new_rev="`get_revision ${new_date}`"
if [ "${run_if_unchanged}" != "true" -a "${old_rev}" = "${new_rev}" ]; then
  echo "Both {$old_date} and {$new_date} correspond to r${new_rev}"\
       "-- skipping nightly build." >unchanged.log
  exit 0
fi

# Do everything twice -- once for the 24 hours old SCST, and once
# for the current one.
for logfile in old new ; do

   # Remove the old scst directory.
   rm -rf "${ABT_TMPDIR}"
   mkdir -p "${ABT_TMPDIR}/scst"

   # Remove old short and verbose log files, and start the new ones.
   for ext in short verbose ; do
      echo > ${logfile}.$ext
   done

   # Choose the current SCST, or one from 24 hours ago.
   if [ ${logfile} = "old" ] ; then
      date="$old_date"
      rev="$old_rev"
   else
      date="$new_date"
      rev="$new_rev"
   fi

   # Check out and run the tests.
   runcmd ${logfile}							\
          "Checking out SCST source tree"				\
          "if svn info . >/dev/null 2>&1; then				\
             svn co -q -r {${date}} ${scst_repo} ${ABT_TMPDIR}/scst;	\
           else								\
             ( rmdir ${ABT_TMPDIR}/scst &&				\
               git clone ${scst_repo} ${ABT_TMPDIR}/scst &&		\
               cd ${ABT_TMPDIR}/scst && git reset --hard ${rev} );	\
           fi" &&
   runcmd ${logfile}							\
          "Running regression tests"					\
          "cd ${ABT_TMPDIR}/scst &&					\
           scripts/run-regression-tests -k -d ${ABT_TMPDIR}/regtest	\
           -j ${ABT_JOBS} -q ${ABT_KERNELS}"
   runcmd ${logfile}				\
          "Cleaning up"				\
          "rm -rf ${ABT_TMPDIR}"

   tail -n +4 ${logfile}.verbose >>${logfile}.short

done

#----------------------------------------------------------------------------
# Prepare results and send
#----------------------------------------------------------------------------

# 'final' shows the difference between the old and new results
echo                                                >  final
echo "Nightly build on $ABT_MACHINE ($ABT_DETAILS)" >> final
echo "started at $ABT_START and compared r${old_rev} with r${new_rev}." \
                                                    >> final

# If the results differ from 24 hours ago, print extra stuff.
diff -u old.short new.short > diff.short
changed=$?

if [ $changed != 0 ] ; then
   echo "Results differ from 24 hours ago"      >> final
   changed_str=""
else
   echo "Results unchanged from 24 hours ago"   >> final
   changed_str="(unchanged) "
fi

if [ $changed != 0 ] ; then
   echo "=================================================" >> final
   echo "== Difference between 24 hours ago and now     ==" >> final
   echo "=================================================" >> final
   echo                                                     >> final
   cat diff.short                                           >> final
   echo                                                     >> final
fi

# Always show the current results.
echo                                                     >> final
echo "=================================================" >> final
echo "== Current results                             ==" >> final
echo "=================================================" >> final
cat new.short >> final
echo                                                     >> final

if [ $changed != 0 ] ; then
   echo "=================================================" >> final
   echo "== Results from 24 hours ago                   ==" >> final
   echo "=================================================" >> final
   cat old.short                                            >> final
   echo                                                     >> final
fi

# Use the conf/<tag>.sendmail script to email the results.
conf/$ABT_MACHINE.sendmail \
   ${sendmail_opts} \
   "$changed_str$ABT_START $(basename "$scst_repo") nightly build ($ABT_MACHINE, $ABT_DETAILS)" \
   final > sendmail.log 2>&1
