#!@KSH@
set -x

# $1 = error number
# terminates test execution with an informative log message
# outputs tcbuild settings to log
function exit_err {
  ERRCODE=$1
  case ${ERRCODE} in
   20) echo "ERROR: test program exited with non-zero status" ;;
   30) echo "ERROR: stdout normalizer (new) exited with non-zero status" ;;
   40) echo "ERROR: stderr normalizer (new) exited with non-zero status" ;;
   50) echo "ERROR: stdout copy exited with non-zero status" ;;
   60) echo "ERROR: stderr copy exited with non-zero status" ;;
   70) echo "ERROR: stdout normalizer (old) exited with non-zero status" ;;
   80) echo "ERROR: stdout normalizer (old) exited with non-zero status" ;;
   90) echo "ERROR: stdout diff mismatch" ;;
   100) echo "ERROR: stderr diff mismatch" ;;
   110) echo "ERROR: Unknown file type in tester" ;;
   *) echo "ERROR: unknown error" ;;
  esac

  echo tcbuild configuration at failure:
  ${SS_COMPILER} ${SS_DEFAULT_COMPILER_FLAGS} ${SS_COMPILER_FLAGS} --settings "${TS_HOME_DIRECTORY}/$1"

  exit ${ERRCODE}
}

ERRCODE=0
PROGNAME=$1
TESTBASE=$2

# Clear files
> stdout.new
> stdout.new.norm
> stdout.old
> stdout.old.norm
> stderr.new
> stderr.new.norm
> stderr.old
> stderr.old.norm

# Get input (note stdin only reliably works on sequential backend)
if [[ -r "${TS_HOME_DIRECTORY}/${TESTBASE}.stdin" ]] ; then
  cp -f ${TS_HOME_DIRECTORY}/${TESTBASE}.stdin stdin.old || if [[ ${ERRCODE} = "0" ]] ; then ERRCODE=55 ; fi
else
  > stdin.old
fi

# get args
if [[ -r "${TS_HOME_DIRECTORY}/${TESTBASE}.args" ]] ; then
  PROGARGS=`cat ${TS_HOME_DIRECTORY}/${TESTBASE}.args` || if [[ ${ERRCODE} = "0" ]] ; then ERRCODE=57 ; fi
  PROGARGS=`eval echo ${PROGARGS}` # expand embedded env vars
else
  PROGARGS=
fi

# Run
# We run using a "watchdog" script which kills the program
# if it outputs over 5000 lines, or goes over 5 minutes with no output
# (this prevents infinite loops and deadlocks from halting 
# the progress of our regression tester)
# Also, limit the logging of stderr to 5000 lines.
set +x
cmd='${TS_BUILD_DIRECTORY}/bin/watchdog 300 5000 ${SS_TCRUN} "./${PROGNAME}" ${PROGARGS} < stdin.old > stdout.new 2> stderr.new'
eval echo "+" '"'"$cmd"'"'
( eval $cmd ) || ERRCODE=20
set -x

# Decide if we need to retry due to a system-level error
SYSERR=`grep -e "Interactive/Debug jobs limit" stdout.new stderr.new`
if [[ ! -z "${SYSERR}" ]] ; then
  echo "${SYSERR}"
  echo "*** ENCOUNTERED A SYSTEM ERROR - RETRYING RUN ***"
  exec $0 "$PROGNAME" "$TESTBASE"
fi

# Normalize
if [[ -x "${TS_HOME_DIRECTORY}/${TESTBASE}.norm" ]] ; then
  NORMALIZER="${TS_HOME_DIRECTORY}/${TESTBASE}.norm"
else
  if [[ ! -z "${SS_NORMALIZER}" && -x "${SS_NORMALIZER}" ]] ; then
	NORMALIZER="${SS_NORMALIZER}"
  else
	NORMALIZER="cat"
  fi
fi
${NORMALIZER} < stdout.new > stdout.new.norm || if [[ ${ERRCODE} = "0" ]] ; then ERRCODE=30 ; fi
${NORMALIZER} < stderr.new > stderr.new.norm || if [[ ${ERRCODE} = "0" ]] ; then ERRCODE=40 ; fi

# Validate
if [[ -r "${TS_HOME_DIRECTORY}/${TESTBASE}.stdout" ]] ; then
  cp -f ${TS_HOME_DIRECTORY}/${TESTBASE}.stdout stdout.old || if [[ ${ERRCODE} = "0" ]] ; then ERRCODE=50 ; fi
else
  > stdout.old
fi
if [[ -r "${TS_HOME_DIRECTORY}/${TESTBASE}.stderr" ]] ; then
  cp -f ${TS_HOME_DIRECTORY}/${TESTBASE}.stderr stderr.old || if [[ ${ERRCODE} = "0" ]] ; then ERRCODE=60 ; fi
else
  > stderr.old
fi

${NORMALIZER} < stdout.old > stdout.old.norm || if [[ ${ERRCODE} = "0" ]] ; then ERRCODE=70 ; fi
${NORMALIZER} < stderr.old > stderr.old.norm || if [[ ${ERRCODE} = "0" ]] ; then ERRCODE=80 ; fi

# make sure we diff both before exiting (more useful to see both in log)
diff stdout.old.norm stdout.new.norm || if [[ ${ERRCODE} = "0" ]] ; then ERRCODE=90  ; fi
diff stderr.old.norm stderr.new.norm || if [[ ${ERRCODE} = "0" ]] ; then ERRCODE=100 ; fi

if [[ ${ERRCODE} != "0" ]] ; then
  exit_err ${ERRCODE}
fi 

exit 0
