#!/bin/bash

### cross format read/(write) test ###

PNAME=${PNAME:-./gpsbabel}
REFGPX="reference/expertgps.gpx"	# reference file for all tests
EXCL="exif ozi vitosmt xol navigonwpt gopal"	# exclude formats from test
CAPS=""
TEMPDIR=${GBTEMP:-/tmp}/gb-test-all
CATALOG=/tmp/gb-test-all.done
LOGFILE=/tmp/gb-test-all.log
RNDFILE=/tmp/gb-random.gpx

# options
vg=0
prep=0

function log_entry()
{
    touch $LOGFILE
    echo "-----------------------------------------------------------------------" >> ${LOGFILE}
    date >> ${LOGFILE}
    echo "$*" >> ${LOGFILE}
}

function try_run() # command line
{
    local CMD="$*"
    local RES=0
    
    [ $vg -ne 0 ] && CMD="valgrind -q $CMD"

    ${CMD} > $TEMPDIR/.result 2>&1
    RES=$?
    if [ $RES -ne 0 -o -s $TEMPDIR/.result ]; then
	if [ $RES -ne 0 ]; then
	    echo " -- Uhps --"
	    echo "-----------------------------------------------------------------------"
	    test -s $TEMPDIR/.result && cat $TEMPDIR/.result
	    echo "-----------------------------------------------------------------------"
	else
	    echo ""
	fi
	log_entry "cmd($RES): $CMD"
	test -s $TEMPDIR/.result && cat $TEMPDIR/.result >> ${LOGFILE}
	return 1
    else
	return 0
    fi
}

function STAGE_1 () # type format
{
    local TYP=$1
    local FMT=$2
    local CMD1 CMD2 IFILE OFILE
    
    echo "$CAPS" |
    
    while read type caps format comment; do
    
	for i in $EXCL; do
	    if [ "$format" == "$i" ]; then
		caps="------"
	    fi
	done
	
	grep "$TYP: $FMT & $format" ${CATALOG} > /dev/null && continue
	
	echo -n "testing "
	case $TYP in
	    w)
		echo -n "waypoints"
		caps=${caps:0:2}
		;;
	    t)
		echo -n "tracks"
		caps=${caps:2:2}
		;;
	    r)
		echo -n "routes"
		caps=${caps:4:2}
		;;
	esac

	echo -n ": \"$FMT\" with \"$format\" "
	
	IFILE=$TEMPDIR/$TYP-$FMT
	OFILE=$TEMPDIR/$TYP-$FMT.$format
	
	case $caps in
	    -w)
		echo -n "*"
		CMD1="${PNAME} -$TYP -i $FMT -f $IFILE -o $format -F $OFILE"
		try_run "${CMD1}" || continue
		;;
		
	    rw)
		echo -n "*"
		CMD1="${PNAME} -$TYP -i $FMT -f $IFILE -o $format -F $OFILE"
		try_run "${CMD1}" || continue
		echo -n "*"
		CMD2="${PNAME} -$TYP -i $format -f $OFILE -o $FMT -F $OFILE.$FMT"
		try_run "${CMD2}" || continue
		;;
	esac
	
	echo "*"
	echo "$TYP: $FMT & $format" >> $CATALOG
    done
    return 0
}

function STAGE_0 ()
{
    echo "$CAPS" |
    
    while read type caps format comment; do
    
	for i in $EXCL; do
		if [ "$format" == "$i" ]; then
			caps="------"
		fi
	done
	
	case ${caps:0:2} in
	    rw)
		CMD="${PNAME} -i gpx -f $REFGPX -x nuketypes,routes,tracks -o $format -F $TEMPDIR/w-$format"
		try_run "${CMD}" || continue
		STAGE_1 "w" $format || exit 1
		;;
	    -w)
		CMD="${PNAME} -i gpx -f $REFGPX -x nuketypes,routes,tracks -o $format -F $TEMPDIR/w-$format"
		try_run "${CMD}" || continue
		;;
	esac
	case ${caps:2:2} in
	    rw)
		CMD="${PNAME} -t -i gpx -f $REFGPX -x nuketypes,waypoints,routes -x track,fix=2D -o $format -F $TEMPDIR/t-$format"
		try_run "${CMD}" || continue
		STAGE_1 "t" $format || exit 1
		;;
	    -w)
		CMD="${PNAME} -t -i gpx -f $REFGPX -x nuketypes,waypoints,routes -x track,fix=2D -o $format -F $TEMPDIR/t-$format"
		try_run "${CMD}" || continue
		;;
	esac
	case ${caps:4:2} in
	    rw)
		CMD="${PNAME} -r -i gpx -f $REFGPX -x nuketypes,waypoints,tracks -o $format -F $TEMPDIR/r-$format"
		try_run "${CMD}" || continue
		STAGE_1 "r" $format || exit 1
		;;
	    -w)
		CMD="${PNAME} -r -i gpx -f $REFGPX -x nuketypes,waypoints,tracks -o $format -F $TEMPDIR/r-$format"
		try_run "${CMD}" || continue
		;;
	esac
    done
    rm -f $TEMPDIR/.result
}

rm -rf $TEMPDIR > /dev/null
mkdir -p $TEMPDIR > /dev/null

while [ $# -gt 0 ]; do
    case $1 in
	-s|--start)	# remove catalog. run the full test.
	    rm -f $CATALOG
	    ;;
	-v|--valgrind)
	    vg=1
	    ;;
	-p|--prepare)	# prepare for valgrind check.
	    prep=1
	    ;;
	-c|--clean)
	    trap "rm -fr $TEMPDIR; exit 1" 0 1 2 3 15
	    ;;
	-n|--random)
	    ${PNAME} -i random -w -f - -i random,points=48 -r -f - -i random,points=120 -t -f - -o gpx,gpxver=1.1 -F $RNDFILE
	    REFGPX=/tmp/gb-random.gpx
	    ;;
	-r|--reference)
	    shift
	    REFGPX=$1
	    ;;
    esac
    shift
done

if [ $prep -ne 0 ]; then
    test -s Makefile && make clean
    CFLAGS="-O0" ./configure || exit 1	#  -O0 is suggested by vg.
    make || exit 1
    echo "All fine. You can do now a 'test-all -v'"
    exit 0
fi

if test ! -s $REFGPX; then
    echo "GPX reference \"$REFGPX\" doesn't exist!"
    exit 1
fi

test -s $LOGFILE && rm -f $LOGFILE.bak > /dev/null
touch $LOGFILE
touch $CATALOG

log_entry "test-all started."
echo "Catalog: $CATALOG" >> $LOGFILE

CAPS=`${PNAME} -^2 | grep "^file"`
STAGE_0
