#! /bin/bash

(
if [ $# != 0 -a "$1" == "--mono" ]; then
  exeprefix=mono
  shift
fi

if [ $# != 0 ]; then
  targets=$*
  for filename in $targets; do
    if [ ! -d $filename ]; then
      echo "$filename is not a directory!"
      continue;
    fi
  done
else
  targets=*
fi

if [[ "$(uname -s)" == "Linux" ]]; then
  exeprefix=mono
fi

if [ exeprefix ]; then
  echo "Using $exeprefix"
fi

testCount=0
failCount=0

for filename in $targets; do
  if [ $filename == "lib" -o ! -d $filename ]; then continue; fi
  echo $filename

  found=0
  for datafile in "$filename"/*.data; do
    if [ ! -f $datafile ]; then continue; fi
    found=1
    break
  done

  if [ $found = 0 ]; then
    echo "No data files found in subdirectory!"
    continue
  fi

  for grs in "$filename"/*.grs; do
    echo -n "- $grs:"
    if [ ! -f $grs.data ]; then
      echo -e "\nOutput data file for $grs not found!"
      continue
    fi

    $exeprefix ../bin/GrShell.exe $grs < /dev/null 2>&1 | awk "BEGIN { testnum = 0 }
      {sub(\"\\r\$\", \"\")}
      /^All attributes/ {
        testnum++
        if ((getline identity < \"$grs.data\") <= 0)
          fail(testnum, \"\n  No reference data for Test \" testnum \"!\")
        sub(\"\\r\$\", \"\", identity)
        if(\$5 != identity)
          fail(testnum, \"\n  Test \" testnum \" FAILED! Expected identity = \" identity \", Found identity = \" \$5)

        testnum++
        if ((getline type < \"$grs.data\") <= 0)
          fail(testnum, \"\n  No reference data for Test \" testnum \"!\")
        sub(\"\\r\$\", \"\", type)
        if(\$8 != type)
          fail(testnum, \"\n  Test \" testnum \" FAILED! Expected type = \" type \", Found type = \" \$8)

        getline
        sub(\"\\r\$\", \"\")
        while(\$0 ~ /^ - /) {
          testnum++
          value = getAttribute(4)
          getline correctvalue < \"$grs.data\"
          sub(\"\\r\$\", \"\", correctvalue)
          if(value != correctvalue)
            fail(testnum, \"\n  Test \" testnum \" FAILED! Expected value of attribute = \" correctvalue \", Found \" value)
          getline
          sub(\"\\r\$\", \"\")
        }
      }
      /(^The available attributes for)|(^(Node|Edge|Object|Transient object|node|edge|object|transient object) types)|(^(Sub|Super) types of (Node|Edge|Object|Transient object|node|edge|object|transient object) type)/ {
        getline
        sub(\"\\r\$\", \"\")
        while(\$0 ~ /^ - /) {
          testnum++
          value = \$0
          getline correctvalue < \"$grs.data\"
          sub(\"\\r\$\", \"\", correctvalue)
          if(value != correctvalue)
            fail(testnum, \"\n  Test \" testnum \" FAILED! Expected value of attribute = \" correctvalue \", Found \" value)
          getline
          sub(\"\\r\$\", \"\")
        }
      }
      /The graph is/ {
        testnum++
        if ((getline correctval < \"$grs.data\") <= 0)
          fail(testnum, \"\n  No reference data for Test \" testnum \"!\")
        sub(\"\\r\$\", \"\", correctval)
        if(\$4 != correctval) {
          print \"\n    Wrong graph validation result at test \" testnum \", Expected = \" correctval \", Found = \" \$4 > \"/dev/stderr\"
          getline
          while(\$1 == \"CAE:\") {
            print \"    \" \$0 > \"/dev/stderr\"
            getline
          }
          fail(testnum, 0)
        }
      }
      /^> / {
        fail(testnum, \"\n  Test FAILED! It is waiting for user input!\")
      }
      /Sequence done/ { time += \$7 }
      /analyzed in/ { time += \$(NF-1) }
      /generated in/ { time += \$(NF-1) }
      /matches found/ {
        testnum++
        if ((getline correctmatches < \"$grs.data\") <= 0)
          fail(testnum, \"\n  No reference data for Test \" testnum \"!\")
        sub(\"\\r\$\", \"\", correctmatches)
        if(\$2 != correctmatches)
          fail(testnum, \"\n  Test \" testnum \" FAILED! Expected matches = \" correctmatches \", Found matches = \" \$2)
      }
      /rewrites performed/ {
        testnum++
        if ((getline correctrewrites < \"$grs.data\") <= 0)
          fail(testnum, \"\n  No reference data for Test \" testnum \"!\")
        sub(\"\\r\$\", \"\", correctrewrites)
        if(\$2 != correctrewrites)
          fail(testnum, \"\n  Test \" testnum \" FAILED! Expected rewrites = \" correctrewrites \", Found rewrites = \" \$2)
      }
      /Number/ {
        testnum++
        if ((getline correctnum < \"$grs.data\") <= 0)
          fail(testnum, \"\n  No reference data for Test \" testnum \"!\")
        sub(\"\\r\$\", \"\", correctnum)
        if(\$8 != correctnum)
          fail(testnum, \"\n  Test \" testnum \" FAILED! Expected number = \" correctnum \", Found \" \$0)
      }
      /value of attribute/ {
        testnum++
        value = getAttribute(7)
        if ((getline correctvalue < \"$grs.data\") <= 0)
          fail(testnum, \"\n  No reference data for Test \" testnum \"!\")
        sub(\"\\r\$\", \"\", correctvalue)
        if(value != correctvalue)
          fail(testnum, \"\n  Test \" testnum \" FAILED! Expected value of attribute = \" correctvalue \", Found \" value)
      }
      /value of variable/ {
        testnum++
        value = getAttribute(10)
        if ((getline correctvalue < \"$grs.data\") <= 0)
          fail(testnum, \"\n  No reference data for Test \" testnum \"!\")
        sub(\"\\r\$\", \"\", correctvalue)
        if(value != correctvalue)
          fail(testnum, \"\n  Test \" testnum \" FAILED! Expected value of variable = \" correctvalue \", Found \" value)
      }
      /reported back:/ {
        testnum++
        value = \"warning reported back\"
        if ((getline correctvalue < \"$grs.data\") <= 0)
          fail(testnum, \"\n  No reference data for Test \" testnum \"!\")
        sub(\"\\r\$\", \"\", correctvalue)
        if(value != correctvalue)
          fail(testnum, \"\n  Test \" testnum \" FAILED! Expected value of warning reported back = \" correctvalue \", Found \" value)
      }
      /Evaluating Sequence Expression done/ {
        testnum++
        value = getAttribute(10)
        if ((getline correctvalue < \"$grs.data\") <= 0)
          fail(testnum, \"\n  No reference data for Test \" testnum \"!\")
        sub(\"\\r\$\", \"\", correctvalue)
        if(value != correctvalue)
          fail(testnum, \"\n  Test \" testnum \" FAILED! Expected value of sequence expression evaluation = \" correctvalue \", Found \" value)
      }
      /Executing Graph Rewrite Sequence done/ {
        testnum++
        value = getAttribute(11)
        if ((getline correctvalue < \"$grs.data\") <= 0)
          fail(testnum, \"\n  No reference data for Test \" testnum \"!\")
        sub(\"\\r\$\", \"\", correctvalue)
        if(value != correctvalue)
          fail(testnum, \"\n  Test \" testnum \" FAILED! Expected value of rewrite sequence execution = \" correctvalue \", Found \" value)
      }
      END {
        if(failed) exit 1

        if((getline noline < \"$grs.data\") > 0)
          fail(testnum, \"\n  Unexpected end of test after Test \" testnum \"!\")

        print \" Success. Total told time: \" time \" ms\"
      }

      function getAttribute(startindex)
      {
        if(startindex > NF) return \"\"

        value = \$startindex
        for(i = startindex + 1; i <= NF; i++)
        {
          value = value \" \" \$i
        }
        return value
      }

      function fail(testnum, string)
      {
        if(string)
          print string > \"/dev/stderr\"
        failed = 1
        exit 1
      }"

    if [ "$?" -ne 0 ]; then
      let failCount++
    fi
    let testCount++
  done
done

if [ "$failCount" -gt 0 ]; then
    echo "Overall result: $failCount of $testCount tests FAILED!"
else
    echo "Overall result: all($testCount) tests succeeded."
fi
) 2>&1 | tee test-`date +%Y%m%d-%H%M%S`.log
