#!/bin/sh

set -e

check()
{
    ZZOPTS="$1"
    CMD="$2"
    ALIAS="$3"
    CHECK="$4"
    echo -n " $(echo "$ALIAS .............." | cut -b1-18) "
    MD5="$(eval "$ZZUF -m $ZZOPTS $CMD" 2>/dev/null | cut -f2 -d' ')"
    if [ -n "$CHECK" ]; then
        REFMD5="$CHECK"
    fi
    if [ -z "$REFMD5" ]; then
        REFMD5="$MD5"
        echo "$MD5"
    else
        TESTED=$(($TESTED + 1))
        if [ "$MD5" != "$REFMD5" ]; then
            FAILED=$(($FAILED + 1))
            echo "$MD5 FAILED"
        else
            echo 'ok'
        fi
    fi
}

seed=$((0+0$1))
DIR="$(dirname "$0")"
ZZUF="$DIR/../src/zzuf"
ZZCAT="$DIR/zzcat"
if [ ! -f "$ZZCAT" ]; then
  echo "error: test/zzcat is missing"
  exit 1
fi
if file /bin/cat | grep -q 'statically linked'; then
  STATIC_CAT=1
fi
if file /bin/dd | grep -q 'statically linked'; then
  STATIC_DD=1
fi
FAILED=0
TESTED=0

echo "*** running zzuf test suite ***"
echo "*** using seed $seed ***"

for r in 0.0 0.00001 0.001 0.1 10.0; do
    for type in 00 ff text random; do
        file="$DIR/file-$type"
        ZZOPTS="-s $seed -r $r"
        case $file in
          *text*) ZZOPTS="$ZZOPTS -P '\n'" ;;
        esac
        echo "*** file $file, ratio $r ***"
        REFMD5=""
        if [ $r = 0.0 -a $type = 00 ]; then
            check="bb7df04e1b0a2570657527a7e108ae23"
            echo "*** should be $check ***"
            check "$ZZOPTS" "< $file" "zzuf" "$check"
        else
            check "$ZZOPTS" "< $file" "zzuf"
        fi
        for n in 1 2 3; do
            check "$ZZOPTS" "$ZZCAT $n $file" "zzcat $n"
        done
        if [ "$STATIC_CAT" = "" ]; then
            check "$ZZOPTS" "cat $file" "cat"
            check "$ZZOPTS" "-i cat < $file" "|cat"
        fi
        if [ "$STATIC_DD" = "" ]; then
            check "$ZZOPTS" "dd bs=65536 if=$file" "dd(bs=65536)"
            check "$ZZOPTS" "dd bs=1111 if=$file" "dd(bs=1111)"
            check "$ZZOPTS" "dd bs=1024 if=$file" "dd(bs=1024)"
            check "$ZZOPTS" "dd bs=1 if=$file" "dd(bs=1)"
        fi
        case $file in
          *text*)
            # We don't include grep or sed when the input is not text, because
            # they put a newline at the end of their input if it was not there
            # initially. (Linux sed doesn't, but OS X sed does.)
            check "$ZZOPTS" "head -- -n 9999 $file" "head -n 9999"
            check "$ZZOPTS" "tail -- -n 9999 $file" "tail -n 9999"
            check "$ZZOPTS" "tail -- -n +1 $file" "tail -n +1"
            check "$ZZOPTS" "grep -- -a '' $file" "grep -a ''"
            check "$ZZOPTS" "sed -- -e n $file" "sed -e n"
            #check "$ZZOPTS" "cut -- -b1- $file" "cut -b1-"
            check "$ZZOPTS" "-i head -- -n 9999 < $file" "|head -n 9999"
            check "$ZZOPTS" "-i tail -- -n 9999 < $file" "|tail -n 9999"
            check "$ZZOPTS" "-i tail -- -n +1 < $file" "|tail -n +1"
            check "$ZZOPTS" "-i grep -- -a '' < $file" "|grep -a ''"
            check "$ZZOPTS" "-i sed -- -e n < $file" "|sed -e n"
            #check "$ZZOPTS" "-i cut -- -b1- < $file" "|cut -b1-"
            ;;
        esac
    done
done

if [ "$FAILED" != 0 ]; then
    echo "*** $FAILED tests failed out of $TESTED ***"
    exit 1
fi
echo "*** all $TESTED tests OK ***"

exit 0

