#!/bin/bash

set -e
$INCLUDE_FUNCS

logfile=$LOGDIR/034.status

file=empty-file


function Filter
{
	filt=$1
	exp=$2

	$BINdflt st -C -f $filt $file > $logfile
	if [[ `wc -l < $logfile` -ne $exp ]]
	then
		cat $logfile
		$ERROR "Status output wrong - filter $filt, expected $exp."
	fi
}

function FiltMTOGNDA
{
	Filter meta $1
	Filter text $2
	Filter owner $3
	Filter group $4
	Filter new $5
	Filter deleted $6
	Filter any $7

	$SUCCESS "Trial run $1$2$3$4$5$6$7 ok."
}

export FSVS_DIR_SORT
# Keep the dir_sort option at the default *after* the loop; that's 
# necessary for tests afterwards.
for FSVS_DIR_SORT in yes no
do
	$INFO "Using dir_sort=$FSVS_DIR_SORT."

	$PREPARE_DEFAULT > /dev/null
	cd $WC



	# without any change?
	FiltMTOGNDA 0 0 0 0 0 0 0

	# meta-data change.
	touch -t 200101270007 $file
	FiltMTOGNDA 1 0 0 0 0 0 1

	# set as known state.
	$BINdflt ci -m 1

	# text change, meta-data same
	echo aiikortv > $file
	touch -t 200101270007 $file
	FiltMTOGNDA 0 1 0 0 0 0 1

	# text and meta-data change
	echo adehlnor > $file
	touch -t 200210291240 $file

	FiltMTOGNDA 1 1 0 0 0 0 1


	# deleted
	rm $file
	FiltMTOGNDA 0 1 0 0 0 1 1

	# replaced
	mkdir $file
	FiltMTOGNDA 1 1 0 0 1 1 1


	$INFO "Testing removed directories."

	mkdir -p a/b/c/d a/b/c/e a/b/d a/h/u a/h/j
	( cd a/h ; touch -d yesterday some files in dir )
	$BINq ci -m 2
	if [[ `$BINdflt st -o verbose=none,status a -N -N` == 'N...  ' ]]
	then
		$ERROR "Hierarchy a not committed"
	fi
	rmdir a/b/c/d a/b/c/e a/b/c a/h/u

	$BINdflt st -C -o filter=deleted > $logfile
	if [[ `wc -l < $logfile` -ne 4 || 
		`grep -w dir < $logfile | wc -l` -ne 4 ||
		`grep a/ < $logfile | wc -l` -ne 4 ]]
	then
		cat $logfile
		$ERROR "Status output wrong (deleted directories #1)"
	fi

	# The parent directories are changed, and that gets counted, too.
	$BINdflt st -C -o filter=text > $logfile
	if [[ `wc -l < $logfile` -ne 6 || 
		`grep a/ < $logfile | wc -l` -ne 6 ]]
	then
		cat $logfile
		$ERROR "Status output wrong (deleted directories #2)"
	fi

	date > a/h/some
	date > a/h/dir

	$BINdflt st -C > $logfile
	if [[ `wc -l < $logfile` -ne 8 || 
		`grep a/ < $logfile | wc -l` -ne 8 ]]
	then
		cat $logfile
		$ERROR "Status output wrong (deleted directories #3)"
	fi
done

$SUCCESS "Ok, filter works."

# set as known state.
$BINq ci -m 2 -o delay=yes

$INFO "Testing dir_exclude_mtime"

mkdir -p test1
$BINdflt ci -m 3
# wait some time after checkin
sleep 2
# change mtime of parent folder
touch test1/test2
# remove fake temp. file
rm    test1/test2
# test option
$BINdflt st -odir_exclude_mtime=true > $logfile

if [[ `wc -l < $logfile` -gt 0 ]]
then
  echo "logfile contains entries"
  cat $logfile
  $ERROR "dir_exclude_mtime option does not work"
fi

if ! $BINdflt st -ostop_change=true -odir_exclude_mtime=true
then 
  $ERROR "stop_change returns true in conjunction with dir_exclude_mtime"
fi

$SUCCESS "dir_exclude checks ok."

$PREPARE_DEFAULT > /dev/null
cd $WC

$INFO "Testing color output."

function HasEscape
{
	# I cannot make grep and egrep understand \x1b.
  if $BINdflt st -o stat_color=yes | perl -e 'exit (0 == grep(/\x1b\[0;0m/, <STDIN>))'
	then
	  $SUCCESS "$1 colorized"
	else
	  $ERROR "$1 not colorized"
	fi
}

echo aaa > hazgr
HasEscape "New"
$BINq ci -m1
echo aaar > hazgr
HasEscape "Changed"
$BINq ci -m1
rm hazgr
HasEscape "Deleted"



# Butterfly test.
# This checks the assertion BUG_ON(entry already output) for various inode 
# number sortings.
$INFO "Checking for inode dependencies."
cd ..
$PREPARE_CLEAN > /dev/null
cd $WC1

perl -e 'for $i (0 .. 15) { 
	$b = (($i & 5) << 1) | (($i & 0xa) >> 1);
	$a = (($b & 3) << 2) | (($b & 0xc) >> 2);
	for $c ( $a, $a ^ 0x1f)
	{
		$f= $c <= 9 ? $c : chr($c + 64+32+1-10);
		mkdir($f) || die "mkdir $f: $!"; 
		open(F, "> $f/file-$f") || die "touch file-$a: $!";
	}
}'

# Now move the directories into one another.
perl -e ' while (1)
{
	($g, $l)=reverse sort grep(/^\w$/, <?>);
	last if !defined($l);

	rename($g, $l . "/" . $g) || die "rename($g, $l): $!";
} '


$BINdflt st > $logfile
$BINq ci -m1

for a in z w r q k f d c 9 6
do
	find . -name file-$a -exec rm {} \;
	$BINdflt st > $logfile
done
$INFO "Files ok."

for a in q k f d c 9 6
do
	find . -depth -name $a -exec rm -r {} \;
	$BINdflt st > $logfile
done

$SUCCESS "Status seems to work regardless of the inode numbering."
