#!/bin/bash

set -e 
$PREPARE_CLEAN > /dev/null
$INCLUDE_FUNCS
cd $WC

# To test:
# - ignoring a file
#   - via shell-pattern
#   - pcre
# - not ignoring a file (take-pattern)
# - all of these in subdirectories

logfile=$LOGDIR/011.ignore
logfile_all=$logfile.all


export PREFIX=igntest
export TAKE=TAKE
export IGNORE=IGN
# To separate changed directories from wanted/not wanted files,
# we grep for this postfix.
# Change caused by using tmpfs, which (correctly!) changed the directories'
# mtime - using ramfs before didn't do that.
export POSTFIX=txt

# delete the old ignore file
ign_file=`$PATH2SPOOL $(pwd) Ign`
test -e $ign_file && rm $ign_file
# remove old test files
find . -depth -iname "*$PREFIX*$POSTFIX" -exec rm -rf {} \;

# create some files
# Matrix:            shell          shell-abs      pcre
#  ignored           s.i.IGN        S.i.IGN        p.i.IGN
#  taken             s.t.TAKE       S.t.TAKE       p.t.TAKE
function M()
{
  test -d "$1" || mkdir -p $1
  # s for shell
  # p for perl
  # e for wild-wildcard
	# A for absolute
	# S for absolute, root-based
  for p in s p e S A
  do
    for t in $TAKE $IGNORE
    do
      for a in `seq 1 1`
      do
        echo $p.$t.$a > $1/$PREFIX-$p.$t.$a.$counter.$POSTFIX
        counter=`expr $counter + 1`
      done
    done
  done
}

DIRLIST=". ign-dir1 $IGNORE-s-dir2 ign-dir2/sub ign-dir2/$IGNORE-p-dir3 deep/dir/for/wild/wild/cards"
for d in $DIRLIST
do
  mkdir -p $d
done
$BINq ci -m "create dirs" -o delay=yes

$WC2_UP_ST_COMPARE

# So we have a constant amount of digits (sorted ls)
counter=1000

for d in $DIRLIST
do
  M $d
done


$BINdflt st | grep $POSTFIX > $logfile_all
all_new=`wc -l < $logfile_all`
take_new=`grep $TAKE < $logfile_all | wc -l`
echo $all_new new files, $take_new to take.

PATTERN_COUNT=15
# We need the patterns in the order take, ignore.
# Test the --prepend here, too.
$BINq ignore "./**$PREFIX-s**" "PCRE:.*$PREFIX-p\."
$BINq ignore prepend "take,./**$PREFIX-s.$TAKE**" "take,PCRE:.*$PREFIX-p\.$TAKE"
$BINq ignore at=1 "take,nocase,./*/dir/*/W?LD/**/$PREFIX-s.$TAKE**"
$BINq ignore at=1 "take,insens,./**/$PREFIX-[ef].$TAKE**"
$BINq ignore "take,/**$PREFIX-S.$TAKE**" "/**$PREFIX-S**"
$BINq ignore "take,$WC/**$PREFIX-A.$TAKE**" "$WC/**$PREFIX-A**"
$BINq ignore "insens,./**/$PREFIX-[ef]**"
$BINq ignore prepend "DEVICE:<0" "DEVICE:>=0xff:0xff"

ignored_file=$PREFIX-perinode-$POSTFIX
touch $ignored_file
$BINq ignore prepend `perl -e '@f=stat(shift); $f[1] || die $!; printf "INODE:%d:%d:%d", $f[0] >> 8, $f[0] & 0xff, $f[1];' $ignored_file`

# this should never match
$BINq ignore prepend "DEVICE:0xff:0xff"

if [[ `$BINdflt ignore dump  | wc -l` -eq $PATTERN_COUNT ]]
then
  $SUCCESS '"ignore dump" returns the correct number of lines'
else
  $ERROR '"ignore dump" gives bad number of lines'
fi

cd ign-dir1
if [[ `$BINdflt ignore dump  | wc -l` -eq $PATTERN_COUNT ]]
then
  $SUCCESS '"ignore dump" works in subdirectories'
else
  $ERROR '"ignore dump" wrong in subdirs?'
fi
cd ..


# Comparing strings with embedded newlines doesn't seem to work,
# so we take the MD5 of the returned lists
before=`$BINdflt ignore dump | md5sum`
transfer=`$BINdflt ignore dump | $BINdflt ignore load`
after=`$BINdflt ignore dump | md5sum`
if [[ $transfer = "$PATTERN_COUNT patterns loaded." && $after = $before ]]
then
  $SUCCESS "'ignore dump | ignore load' gives identity"
else
  echo "**** Got: $after"
  echo "**** expected: $before"
  echo "**** Transfer said: $transfer"
  $ERROR "ignore dump/load error"
fi


$BINdflt st | grep $POSTFIX > $logfile
filt_new=`wc -l < $logfile`
echo $filt_new after filtering.
if [[ $filt_new -ne $take_new ]]
then
  cat $logfile
  $ERROR "   mismatch - $filt_new got, $take_new expected!"
fi

echo "Testing for files which should not be found ..."
if $BINdflt st | grep $POSTFIX | grep $IGNORE | grep -v $TAKE > /dev/null 2>&1
then
  $ERROR "other files found??"
fi

echo "Testing for files which should be found ..."
take_filt=`$BINdflt st | grep $TAKE | wc -l`
if [[ $take_filt -ne $filt_new ]]
then
  $ERROR "  wrong files found??\n"
fi


committed=`$BINdflt ci -m "ci" | grep "^N" | wc -l`
echo "     committed $committed files, expect $filt_new"
if [[ "$committed" -ne "$filt_new" ]]
then
  $ERROR "change in which files are committed"
fi

# update other wc
  pushd $WC2 > /dev/null
  echo "     up-x"
  $BINq up

  # If we find differences in ignore files, it is ok - they should not
  # be committed, after all.
  # Files that should be taken should have no difference.
  $COMPARE -x "IGN|igntest-perinode" $WC/ $WC2/ > $logfile
  after_up=`grep $TAKE < $logfile || true`
  if [[ "$after_up" = "" ]]
  then
    $SUCCESS "update gets no ignored files"
  else
    $ERROR "update gets ignored files!"
  fi
popd > /dev/null

# Restore wcs
echo "Restoring working copies to an equal state."
find . -depth -iname "*$PREFIX*" -exec rm -rf {} \;
$BINq st
$BINq ci -m asf 
  pushd $WC2 > /dev/null
  $BINq up 
popd > /dev/null


echo "Testing pattern list edits."
echo "" | $BINq ignore load
#if [[ `cat $ign_file` == 0 ]]
if [[ -e $ign_file ]]
then
  cat $ign_file
  ls -la $ign_file
  $ERROR "not emptied"
else
  $SUCCESS "empty state."
fi


echo "Ignore lists with comments"
$BINq ignore prepend group:ignore,./1
echo "# ignore me!!" | $BINq ignore load
if [[ -e $ign_file ]]
then
  cat $ign_file
  ls -la $ign_file
  $ERROR "not emptied"
else
  $SUCCESS "empty state."
fi


$BINq ignore prepend group:ignore,./1
$BINq ignore append  group:take,./3
$BINq ignore at=1               ./2
$BINq ignore prepend group:take,./0
file=dump.txt
$BINq ignore dump > $file
if ( 
	echo group:take,./0 ; 
	echo group:ignore,./1 ; 
	echo group:ignore,./2 ; 
	echo group:take,./3 ) | cmp -s - $file 
then
  $SUCCESS "pattern edit operations work."
else
  cat $file
  $ERROR "dump gives wrong results"
fi

rm $file

$WC2_UP_ST_COMPARE


# Create a directory tree, where something deep within is ignored.
# Get a defined state
$BINq ci -m1 -odelay=yes
mkdir -p a/b/c/d/e/f/g/h
touch a/b/c/d/e/f/g/h/$STG_UTF8
$BINdflt ignore '/**/a/**/c/*/e/f'
if $BINdflt st | grep "$STG_UTF8"
then
  $ERROR "Deep ignores in build_tree doesn't work."
else
  $SUCCESS "Deep ignores in build_tree work."
fi


$BINq ci -mO

# Now we put the WAA in there and test again, to see whether it gets 
# correctly ignored.
new=$WC/waa
cp -a $FSVS_WAA $new
FSVS_WAA=$new
# Only "." and "waa" may be shown - nothing below.
if [[ `$BINdflt st -C | wc -l` -le 2 ]]
then
  $SUCCESS "WAA gets ignored"
else
	$BINdflt st -C
  $ERROR "WAA would get versioned"
fi


# Test whether the absolute patterns warn
bad=/$RANDOM-$RANDOM/does-not-exist
if $BINdflt ignore "$bad" -o ignpat-wcbase=stop 2>/dev/null
then
  $ERROR "Bad absolute ignore pattern taken"
fi
if ! $BINdflt ignore "$bad" -W ignpat-wcbase=ignore
then
  $ERROR "Bad absolute ignore pattern not taken"
fi
# Pattern already saved, a simple dump should do the trick
if [[ `( $BINdflt ignore dump -W ignpat-wcbase=always 2>&1 ; true )` != *"WARNING: The absolute shell pattern"*"$bad"*"does neither have the working copy base path"*"nor a wildcard path"* ]]
then
	$BINdflt ignore dump -W ignpat-wcbase=always
  $ERROR "Bad absolute ignore pattern warning not given?"
fi

$SUCCESS "Absolute ignore pattern warnings tests"


# Test the "dir-only" specification
true | $BINdflt ignore load
$BINq ci -m1 -o delay=yes
# now we're clean.
mkdir -p deep/a/b/c/dir
touch deep/fileA
touch deep/a/fileB
touch deep/a/b/fileC
touch deep/a/b/c/fileD
touch deep/a/b/c/dir/file-ok
$BINq ignore 'take,./deep/**ok*' 'dir,take,./deep/**' './deep/**'
# Store the statistic for later.
$BINq ignore test -o group_stats=yes > $logfile
$BINq ci -m1
if [[ `$BINdflt log -v -r HEAD | grep file | wc -l` -eq 1 ]]
then
  $SUCCESS "dir-only pattern looks ok."
else
  $ERROR "wrong commit for dir-only pattern"
fi


# Test group statistics.
l1="Grouping statistics"
l2=`echo -e "9\t1\ttake\ttake,./deep/**ok*"`
l3=`echo -e "8\t4\ttake\tdir,take,./deep/**"`
l4=`echo -e "4\t4\tignore\tgroup:ignore,./deep/**"`
if [[ `cat $logfile` == *"$l1"*"$l2"*"$l3"*"$l4" ]]
then
	$SUCCESS "Group statistics"
else
	echo *"$l1"*"$l2"*"$l3"*"$l4"
	$ERROR "Group statistics output"
fi

# Test match vector reallocation.
$BINq ignore load < /dev/null
$BINq ignore 'take,PCRE:^.*/deep2/((((((((((((((((((((((((((((((((((((((((a))))))))))))))))))))))))))))))))))))))))(/|$)'
$BINq ignore 'ign,./waa/**'
$BINq ignore 'ign,./deep2/**'
# "Generate" data
mv deep deep2
$BINdflt ci deep -m"remove"
if [[ `$BINdflt st | wc -l` -eq 10 ]]
then
  $SUCCESS "Many Parens are okay"
else
  $ERROR "Many Parens went wrong"
fi

