#! /bin/sh
#
# Copyright by The HDF Group.
# Copyright by the Board of Trustees of the University of Illinois.
# All rights reserved.
#
# This file is part of HDF5.  The full HDF5 copyright notice, including
# terms governing use, modification, and redistribution, is contained in
# the files COPYING and Copyright.html.  COPYING can be found at the root
# of the source code distribution tree; Copyright.html can be found at the
# root level of an installed copy of the electronic HDF5 document set and
# is linked from the top-level documents page.  It can also be found at
# http://hdfgroup.org/HDF5/doc/Copyright.html.  If you do not have
# access to either file, you may request a copy from help@hdfgroup.org.
#
# Tests for the h5jam/h5unjam tools

# Determine which filters are available
USE_FILTER_SZIP="@USE_FILTER_SZIP@"
USE_FILTER_DEFLATE="@USE_FILTER_DEFLATE@"
USE_FILTER_SHUFFLE="@USE_FILTER_SHUFFLE@"
USE_FILTER_FLETCHER32="@USE_FILTER_FLETCHER32@"

TESTNAME=h5jam/h5unjam
EXIT_SUCCESS=0
EXIT_FAILURE=1

DUMPER=h5dump               # The dumper to use
DUMPER_BIN=`pwd`/../$DUMPER    # The path of the dumper binary
JAM=h5jam                     # Tool to test
UNJAM=h5unjam                     # Tool to test
JAM_BIN="$RUNSERIAL "`pwd`    # The path of the jam binary
UNJAM_BIN=`pwd`    # The path of the jam binary

CMP='cmp -s'
DIFF='diff -c'
AWK='awk'

nerrors=0
verbose=yes

# The build (current) directory might be different than the source directory.
if test -z "$srcdir"; then
   srcdir=.
fi
TESTFILES="$srcdir/testfiles"


# Print a line-line message left justified in a field of 70 characters
# beginning with the word "Testing".
#
TESTING() {
   SPACES="                                                               "
   echo "Testing $* $SPACES" | cut -c1-70 | tr -d '\012'
}

# Print a line-line message left justified in a field of 70 characters
# beginning with the word "Compare".
#
COMPARE() {
   SPACES="                                                               "
   echo "Compare $* $SPACES" | cut -c1-70 | tr -d '\012'
}

# Print a "SKIP" message
SKIP() {
 TESTING $JAM $@
 echo  " -SKIP-"
}

# 
#  COMPARE_FILES a.h5 b.h5
#    Compare two files, skipping the first line.  This is used to 
#    compare the output of the dumper, skipping the file name which
#    is different.
#    The result is stored in 'compval'.
#
cmpval=0;
COMPARE_FILES() {
	$AWK 'NR > 1' $1 > $1.cmp
	$AWK 'NR > 1' $2 > $2.cmp
 	$CMP $1.cmp $2.cmp 
 	cmpval=$?
        rm -f $1.cmp $2.cmp
}

#  CLEANUP files
#     Clean up named files.
CLEANUP() {
   if test -z "$HDF5_NOCLEANUP"; then
	for i in $*
	do
		rm -f $i
	done
   fi
}

#  SETUP file tocopy
#    Clone a standard input file in the test directory
#  Modification:
#    Was using "cp" command which means file $2 will inherit the permission
#    setting of file $1.  If $1 is read-only, so will $2.  That will cause
#    failure when the test attempts to write it later on.  Changed to use
#    the "cat" command.
#
SETUP() {
	cat < $1 > $2
}

#
#  CHECKFILE orig.h5 compar.h5
#     Check that the test file is the same as an original.
#     The two files are dumped with the dumper, and the output
#     compared with COMPARE_FILES.
#     If the files are the same, the test reports " PASSED",
#     otherwise, it reports "*FAILED*"
CHECKFILE() {
   expected="`dirname $2`/`basename $2 .h5`.out"
   expected_err="`dirname $2`/`basename $2 .h5`.err"
   actual="`basename $1 .h5`.out"
   actual_err="`basename $1 .h5`.err"

   $RUNSERIAL $DUMPER_BIN/$DUMPER $1 >$expected 2>$expected_err
   cat $expected_err >> $expected

   # dump the test file
   COMPARE $2 to $1
   $RUNSERIAL $DUMPER_BIN/$DUMPER $2 >$actual 2>$actual_err
   cat $actual_err >> $actual

   # compare the two files (ignore line 1)
   COMPARE_FILES $actual $expected
   if [ "$cmpval" = 0 ] ; then
      echo " PASSED"
   else
      echo "*FAILED*"
      echo "    Expected result (*.ddl) differs from actual result (*.out)"
      nerrors="`expr $nerrors + 1`"
      test yes = "$verbose" && $DIFF $expected $actual |sed 's/^/    /'
   fi

   # Clean up output files
   if test -z "$HDF5_NOCLEANUP"; then
      rm -f $actual $actual_err
      rm -f $expected $expected_err
   fi
}

#
# CHECK_UB file.h5 user_block_file origfile.h5 
#
#   Check the user block in 'file.h5' is the same as
#   'user_block' (allowing for padding).
#
#   If the original file had a user block before the test
#   then 'compare.h5' is passed.  The user block must be extracted
#   and the test file compared to:
#      cat compare_ub user_block_file.
#
#   This test uses './getub' to extract the user block from 
#   'file.h5', which is compared to the file described above.
#
#   The result is set in variable 'result1'.
#
result1=0;
CHECK_UB_1() {
	hfile="$1"
	ufile="$2"

	# check for third argument (the original file)
	origfile="";
	if [ -n "$3" ];
	then
		origfile="$3"
	fi

	# find the length of the user block to check
	s1=`cat $ufile | wc -c | sed -e 's/ //g'`
	if [ "$s1" = "0" ];
	then
		echo "File "$ufile" is empty"
		result1=1;
	fi

	# Get the size of the original user block, if any.
	if [ -n "$origfile" ];
	then
		# 'tellub' calls H5Fget_user_block to get the size
		#  of the user block
		s2=`$JAM_BIN/tellub $origfile`
		if [ "$s2" = "0" ];
		then
			size=$s1;
			cmpfile=$ufile
		else
			cmpfile="tt2"
			size=`expr $s2 + $s1`
			$JAM_BIN/getub -c $s2 $origfile > $cmpfile
			cat $ufile >> $cmpfile
		fi
	else
		# assume no user block
		s2="0"
		size=$s1;
		cmpfile=$ufile
	fi

	# Extract 'size' bytes from the front of 'hfile'
	# Compare to 'cmpfile', result is set in result1
	tfile="tt1"
	$JAM_BIN/getub -c $size $hfile > $tfile
	res=`cmp $cmpfile $tfile`
	if [ "$?" != "0" ];
	then
		echo $res
		result1=1;
	else
		result1=0;
	fi

	# clean up
	rm -f  $tfile
	if [ "$s2" != "0" ] ;
	then
		rm -f $cmpfile
	fi
}


#  CHECK_NOUB file.h5
#
#  Check that 'file.h5' has no user block.
#  Setst result2 to 1 if there is a user block (fail), 0 if none (pass)

result2=0;

CHECK_NOUB() {
	hfile="$1"

	# call 'ubsize' to get the size of the user block
	ubsize=`$JAM_BIN/tellub $hfile`

	if [ "$?" != "0" ];
	then
		# error
		result2=1;
	else
	if [ "$ubsize" = "0" ];
	then
		# pass
		result2=0;
	else
		# fail
		result2=1;
	fi
	fi
}

#  JAMTEST user_block file.h5 [--clobber] [ofile.h5]
#
#    Test the 'jam' tool:
#      1. figure out the input and output, and the comparision
#         that will be done.
#      2. call 'jam' with the appropriate arguments
#      3. check the user block is correct in the output (Check_UB)
#    If the user block is correct, print "PASSED", else "*FAILED*"
JAMTEST() {
	ufile="$1"
	ifile="$2"
	compare_test=""   # the file to test
	compare_orig=""   # the comparison to test against
	cleanup=""

	# sort out the arguments for the test and the check
	do_clobber="no"
	if [ "$3" = "--clobber" ];
	then
		#  clobber overwrites any existing user block
		do_clobber="yes"
		clobber="--clobber"
		compare_orig=""
		if [ -z "$4" ];
		then
			# output goes to infile, compare ubfile to infile
			ofile=""
			compare_test="$ifile"
		else
			# output goes to $4,  compare ofile to ubfile
			ofile="$4"
			compare_test="$ofile"
		fi
	else
		clobber=""
		# add user block to existing ub, if any 
		if [ -z "$3" ];
		then
			# output goes to infile, compare ubfile to infile
			ofile=""
			compare_test="$ifile"
			cp $ifile xxofile.h5
			compare_orig="xxofile.h5"
			cleanup="$cleanup $compare_orig"
		else
			# output goes to $4,  compare ofile to ubfile
			ofile="$3"
			compare_test="$ofile"
			compare_orig="$ifile"
		fi
	fi

	# call 'jam' with the appropriate arguments
	if [ -n "$ofile" ];
	then
		TESTING h5jam -u `basename $ufile` -i `basename $ifile` -o `basename $ofile` $clobber
		$JAM_BIN/$JAM -u $ufile -i $ifile -o $ofile $clobber
	else
		TESTING jam -u `basename $ufile` -i `basename $ifile` $clobber
		$JAM_BIN/$JAM -u $ufile -i $ifile $clobber
	fi

	#echo "CHECK_UB_1 $compare_test $ufile $compare_orig"
	CHECK_UB_1 $compare_test $ufile $compare_orig

	if [ "$result1" = "0" ] ;
	then
		echo " PASSED"
	else
		echo " *FAILED*"
      		nerrors="`expr $nerrors + 1`"
	fi
 	CLEANUP $cleanup
}
	
# UNJAMTEST  file.h5 [- | --delete] ofile
#
#  Test the 'unjam' tool
#
###fix the working directory here and in jamtest
UNJAMTEST () {
	infile="$1"
	ofile="$3"
	if [ "$2" = "-" ];
	then
		uofile="uofile"
		TESTING h5unjam -i `basename $infile` -o `basename $ofile` "> "`basename $uofile`
		$JAM_BIN/$UNJAM -i $infile -o $ofile > $uofile
	else
	if [ "$2" = "--delete" ];
	then
		uofile="none"
		TESTING h5unjam -i `basename $infile` -o `basename $ofile` --delete
		$JAM_BIN/$UNJAM  -i $infile -o $ofile --delete 

	else
		uofile="$2"
		TESTING h5unjam -i `basename $infile` -u `basename $uofile` -o `basename $ofile`
		$JAM_BIN/$UNJAM  -i $infile -u $uofile -o $ofile
	fi
	fi

	result1=0
	result2=0
	cleanup=""
	if [ "$uofile" != "none" ];
	then
		# sets result1
		CHECK_UB_1 $infile $uofile
		CLEANUP $uofile
	fi

	# sets result2
	CHECK_NOUB $ofile

	if [ "$result1" = "0" -a "$result2" = "0" ];
	then
		echo " PASSED"
	else
		echo " *FAILED*"
	      nerrors="`expr $nerrors + 1`"
	fi
}


##############################################################################
##############################################################################
###			  T H E   T E S T S                                ###
##############################################################################
##############################################################################

JAMTEST $TESTFILES/u10.txt $TESTFILES/tall.h5 ta2.h5
CHECKFILE $TESTFILES/tall.h5 ta2.h5
CLEANUP ta2.h5
JAMTEST $TESTFILES/u511.txt $TESTFILES/tall.h5 ta3.h5
CHECKFILE $TESTFILES/tall.h5 ta3.h5
CLEANUP ta3.h5
JAMTEST $TESTFILES/u512.txt $TESTFILES/tall.h5 ta4.h5
CHECKFILE $TESTFILES/tall.h5 ta4.h5
CLEANUP ta4.h5
JAMTEST $TESTFILES/u513.txt $TESTFILES/tall.h5 ta5.h5
CHECKFILE $TESTFILES/tall.h5 ta5.h5
CLEANUP ta5.h5

SETUP $TESTFILES/tall.h5 ta.h5
JAMTEST $TESTFILES/u10.txt ta.h5 
CHECKFILE $TESTFILES/tall.h5 ta.h5
SETUP $TESTFILES/tall.h5 ta.h5
JAMTEST $TESTFILES/u511.txt ta.h5 
CHECKFILE $TESTFILES/tall.h5 ta.h5
SETUP $TESTFILES/tall.h5 ta.h5
JAMTEST $TESTFILES/u512.txt ta.h5 
CHECKFILE $TESTFILES/tall.h5 ta.h5
SETUP $TESTFILES/tall.h5 ta.h5
JAMTEST $TESTFILES/u513.txt ta.h5 
CHECKFILE $TESTFILES/tall.h5 ta.h5
CLEANUP ta.h5

JAMTEST $TESTFILES/u10.txt $TESTFILES/twithub.h5 tax2.h5
CHECKFILE $TESTFILES/tall.h5 tax2.h5
CLEANUP tax2.h5
JAMTEST $TESTFILES/u511.txt $TESTFILES/twithub.h5 tax3.h5
CHECKFILE $TESTFILES/tall.h5 tax3.h5
CLEANUP tax3.h5
JAMTEST $TESTFILES/u512.txt $TESTFILES/twithub.h5 tax4.h5
CHECKFILE $TESTFILES/tall.h5 tax4.h5
CLEANUP tax4.h5
JAMTEST $TESTFILES/u513.txt $TESTFILES/twithub.h5 tax5.h5
CHECKFILE $TESTFILES/tall.h5 tax5.h5
CLEANUP tax5.h5

JAMTEST $TESTFILES/u10.txt $TESTFILES/twithub513.h5 tax6.h5
CHECKFILE $TESTFILES/tall.h5 tax6.h5
CLEANUP tax6.h5
JAMTEST $TESTFILES/u511.txt $TESTFILES/twithub513.h5 tax7.h5
CHECKFILE $TESTFILES/tall.h5 tax7.h5
CLEANUP tax7.h5
JAMTEST $TESTFILES/u512.txt $TESTFILES/twithub513.h5 tax8.h5
CHECKFILE $TESTFILES/tall.h5 tax8.h5
CLEANUP tax8.h5
JAMTEST $TESTFILES/u513.txt $TESTFILES/twithub513.h5 tax9.h5
CHECKFILE $TESTFILES/tall.h5 tax9.h5
CLEANUP tax9.h5

JAMTEST $TESTFILES/u10.txt $TESTFILES/twithub.h5 --clobber taz2.h5 
CHECKFILE $TESTFILES/tall.h5 taz2.h5
CLEANUP taz2.h5
JAMTEST $TESTFILES/u511.txt $TESTFILES/twithub.h5 --clobber taz3.h5
CHECKFILE $TESTFILES/tall.h5 taz3.h5
CLEANUP taz3.h5
JAMTEST $TESTFILES/u512.txt $TESTFILES/twithub.h5 --clobber taz4.h5 
CHECKFILE $TESTFILES/tall.h5 taz4.h5
CLEANUP taz4.h5
JAMTEST $TESTFILES/u513.txt $TESTFILES/twithub.h5 --clobber taz5.h5 
CHECKFILE $TESTFILES/tall.h5 taz5.h5
CLEANUP taz5.h5

JAMTEST $TESTFILES/u10.txt $TESTFILES/twithub513.h5 --clobber taz6.h5 
CHECKFILE $TESTFILES/tall.h5 taz6.h5
CLEANUP taz6.h5
JAMTEST $TESTFILES/u511.txt $TESTFILES/twithub513.h5 --clobber taz7.h5
CHECKFILE $TESTFILES/tall.h5 taz7.h5
CLEANUP taz7.h5
JAMTEST $TESTFILES/u512.txt $TESTFILES/twithub513.h5 --clobber taz8.h5 
CHECKFILE $TESTFILES/tall.h5 taz8.h5
CLEANUP taz8.h5
JAMTEST $TESTFILES/u513.txt $TESTFILES/twithub513.h5 --clobber taz9.h5 
CHECKFILE $TESTFILES/tall.h5 taz9.h5
CLEANUP taz9.h5

SETUP $TESTFILES/twithub.h5 tay2.h5
JAMTEST $TESTFILES/u10.txt tay2.h5 --clobber
CHECKFILE $TESTFILES/tall.h5 tay2.h5
CLEANUP tay2.h5
SETUP $TESTFILES/twithub.h5 tay3.h5
JAMTEST $TESTFILES/u511.txt tay3.h5 --clobber
CHECKFILE $TESTFILES/tall.h5 tay3.h5
CLEANUP tay3.h5
SETUP $TESTFILES/twithub.h5 tay4.h5
JAMTEST $TESTFILES/u512.txt tay4.h5 --clobber
CHECKFILE $TESTFILES/tall.h5 tay4.h5
CLEANUP tay4.h5
SETUP $TESTFILES/twithub.h5 tay5.h5
JAMTEST $TESTFILES/u513.txt tay5.h5 --clobber
CHECKFILE $TESTFILES/tall.h5 tay5.h5
CLEANUP tay5.h5

SETUP $TESTFILES/twithub513.h5 tay6.h5
JAMTEST $TESTFILES/u10.txt tay6.h5 --clobber
CHECKFILE $TESTFILES/tall.h5 tay6.h5
CLEANUP tay6.h5
SETUP $TESTFILES/twithub513.h5 tay7.h5
JAMTEST $TESTFILES/u511.txt tay7.h5 --clobber
CHECKFILE $TESTFILES/tall.h5 tay7.h5
CLEANUP tay7.h5
SETUP $TESTFILES/twithub513.h5 tay8.h5
JAMTEST $TESTFILES/u512.txt tay8.h5 --clobber
CHECKFILE $TESTFILES/tall.h5 tay8.h5
CLEANUP tay8.h5
SETUP $TESTFILES/twithub513.h5 tay9.h5
JAMTEST $TESTFILES/u513.txt tay9.h5 --clobber
CHECKFILE $TESTFILES/tall.h5 tay9.h5
CLEANUP tay9.h5

SETUP $TESTFILES/twithub.h5 tai1.h5
UNJAMTEST tai1.h5 o10.txt taa1.h5
CHECKFILE $TESTFILES/tall.h5 taa1.h5
CLEANUP taa1.h5 tai1.h5 o10.txt
SETUP $TESTFILES/twithub513.h5 tai2.h5
UNJAMTEST tai2.h5 o512.txt taa2.h5
CHECKFILE $TESTFILES/tall.h5 taa2.h5
CLEANUP taa2.h5 tai2.h5 o512.txt

SETUP $TESTFILES/twithub.h5 tai3.h5
UNJAMTEST tai3.h5 - taa3.h5
CHECKFILE $TESTFILES/tall.h5 taa3.h5
CLEANUP taa3.h5 tai3.h5
SETUP $TESTFILES/twithub513.h5 tai4.h5
UNJAMTEST tai4.h5 - taa4.h5
CHECKFILE $TESTFILES/tall.h5 taa4.h5
CLEANUP taa4.h5 tai4.h5

SETUP $TESTFILES/twithub.h5 taj2.h5
UNJAMTEST taj2.h5 --delete tac2.h5
CHECKFILE $TESTFILES/tall.h5 tac2.h5
CLEANUP tac2.h5 taj2.h5
SETUP $TESTFILES/twithub513.h5 taj3.h5
UNJAMTEST taj3.h5 --delete tac3.h5
CHECKFILE $TESTFILES/tall.h5 tac3.h5
CLEANUP tac3.h5 taj3.h5



if test $nerrors -eq 0 ; then
    echo "All $TESTNAME tests passed."
    exit $EXIT_SUCCESS
else
    echo "$TESTNAME tests failed with $nerrors errors."
    exit $EXIT_FAILURE
fi
