#!/bin/sh
# Hell, this is really difficult with /bin/sh. I want my zsh back!

testdir=tests
fvwmdir=..
myname=`basename $0`
log=$testdir/$myname.log

typeset -i c1
typeset -i c2
typeset -i c3
typeset -i i1
typeset -i i2
typeset -i nopts
typeset -i copts

usage ()
{
  echo "usage: $myname [-0] [-1] [-2] [-a] [make options]"
  echo "  -0: run tests with all options defined and disabled (2 builds)"
  echo "  -1: run tests with one option defined and disabled"
  echo "  -2: run tests with two options defined and disabled"
  echo "  -a: run all possible tests"
  echo "  default is: myname -0 -1"
  echo "  logging output goes to $log and $log.*"
}

#
#parse command line
#
run_depth_0=""
run_depth_1=""
run_depth_2=""
run_all=""
custom=""
while [ -n "$1" ] ; do
  if [ "$1" = "-h" ] ; then
    usage
    exit
  elif [ "$1" = "-?" ] ; then
    usage
    exit
  elif [ "$1" = "-0" ] ; then
    run_depth_0=1
    run_all=""
    custom=1
  elif [ "$1" = "-1" ] ; then
    run_depth_1=1
    run_all=""
    custom=1
  elif [ "$1" = "-2" ] ; then
    run_depth_2=1
    run_all=""
    custom=1
  elif [ "$1" = "-a" ] ; then
    run_depth_0=""
    run_depth_1=""
    run_depth_2=""
    run_all=1
    custom=1
  else
    break;
  fi
  shift
done

MAKE_OPTS="$*"

# set default if nothing was selected
if [ -z "$custom" ]; then
  run_depth_0="1"
  run_depth_1="1"
fi

if [ ! -x ./$myname ] ; then
  echo please run $myname from $testdir
  exit 1
fi
cd $fvwmdir
rm -f "$log"* > /dev/null 2>&1


##################
# some functions #
##################

# clean up before next build
clean_up ()
{
  make clean > /dev/null 2>&1
  make distclean > /dev/null 2>&1
  rm -f config.cache > /dev/null 2>&1
  for i in `find . -name .deps -type d` ; do rm -rf $i; done > /dev/null 2>&1
  for i in `find . -name Makefile` ; do rm -f $i; done > /dev/null 2>&1
  for i in `find . -name "*.o"` ; do rm -f $i; done > /dev/null 2>&1
}

# generate parameter list for configure
disable_options ()
{
  CONFIGURE_OPTS=""
  while [ ! "$1" = "" ]; do
    CONFIGURE_OPTS="$CONFIGURE_OPTS --disable-${BUILD_OPTIONS[$1]}"
    shift
  done
  c3=0
  while [ ! "${BUILD_OPTIONS[$c3]}" = "" ]; do
    echo $CONFIGURE_OPTS | grep -q -- "--disable-${BUILD_OPTIONS[$c3]}" ||
      CONFIGURE_OPTS="$CONFIGURE_OPTS --enable-${BUILD_OPTIONS[$c3]}"
    c3=$c3+1
  done
}

# disable all enabled options and vice versa
reverse_options ()
{
  CONFIGURE_OPTS=`echo $CONFIGURE_OPTS |
           sed -e 's/--enable-/--xyz-/g' |
           sed -e 's/--disable-/--enable-/g' |
           sed -e 's/--xyz-/--disable-/g'`
}

# call configure and make (with logging)
build ()
{
  echo "+++ testing (logfile $1): $CONFIGURE_OPTS" >> $log
  # clean up
  echo "cleaning up..." >> $log
  clean_up
  # configure
  echo "configuring..." >> $log
  echo "./configure $CONFIGURE_OPTS" > $log.$1
  if nice ./configure --enable-extras $CONFIGURE_OPTS >> $log.$1 2>&1; then
    echo ok >> $log
  else
    echo FAILED >> $log
  fi
  # make
  echo "building..." >> $log
  if nice make $MAKE_OPTS > $log.$1 2>&1; then
    echo ok >> $log
  else
    echo FAILED >> $log
  fi
  echo >> $log
}

############################
# end of functions section #
############################

#
# get the list of possible options
#
c1=0
nopts=0
copts=1
for i in `
grep "^\(dnl dummy: \)\?smr_SWITCH" configure.in |
grep -v debug-msgs |
sed -e 's/^.*smr_SWITCH.//g' |
cut -f 1 -d ","`; do
  BUILD_OPTIONS[$c1]="$i"
  OPTIONS="$OPTIONS $i"
  c1=$c1+1;
  nopts=$nopts+1;
  copts=$copts+$copts
done

#
# now do the tests
#
if [ "$run_depth_1" = "1" ] ; then
  i1=$nopts+$nopts
  echo
  echo " +++ running $i1 tests for depth 1 +++"
  echo
  c1=0
  while [ ! "${BUILD_OPTIONS[$c1]}" = "" ]; do
    disable_options $c1
    echo build ${BUILD_OPTIONS[$c1]}_off
    build ${BUILD_OPTIONS[$c1]}_off
    reverse_options
    echo build ${BUILD_OPTIONS[$c1]}_on
    build ${BUILD_OPTIONS[$c1]}_on
    c1=$c1+1
  done
fi

if [ "$run_depth_2" = "1" ] ; then
  i1="$nopts * $nopts + $nopts"
  echo
  echo " +++ running $i1 tests for depth 2 +++"
  echo
  c1=0
  while [ -n "${BUILD_OPTIONS[$c1]}" ]; do
    c2=$c1+1
    while [ -n "${BUILD_OPTIONS[$c2]}" ]; do
      disable_options $c1 $c2
      echo build ${BUILD_OPTIONS[$c1]}_off,${BUILD_OPTIONS[$c2]}_off
      build ${BUILD_OPTIONS[$c1]}_off
      reverse_options
      echo build ${BUILD_OPTIONS[$c1]}_on,${BUILD_OPTIONS[$c2]}_on
      build ${BUILD_OPTIONS[$c1]}_on
      c2=$c2+1
    done
    c1=$c1+1
  done
fi

if [ "$run_depth_0" = "1" ] ; then
  echo
  echo " +++ running 2 tests for depth 0 +++"
  echo
  disable_options
  reverse_options
  echo build all_disabled
  build all_disabled
  disable_options
  echo build all_enabled
  build all_enabled
fi

if [ "$run_all" = "1" ] ; then
  i1=$copts+1
  echo
  echo " +++ running $i1 tests for all combination of options +++"
  echo
  c1=0
  while [ ! "$c1" = "$copts" ]; do
    c2=$c1
    i1=0
    opts_off=""
    while [ ! "$i1" = "$nopts" ]; do
      i2="$c2/2"
      i2="$i2*2"
      if [ "$i2" = "$c2" ]; then
        opts_off="$opts_off $i1"
      fi
      i1=$i1+1
      c2=$c2/2
    done
    disable_options $opts_off
    echo "test $c1 of $copts (logfile: `basename $log.$c1`):"
    echo "$CONFIGURE_OPTS"
    build $c1
    c1=$c1+1
  done
fi
