#!/usr/bin/env bash
DESCRIPTION="\
Description: Run the test suite, record output
"

USAGE="\
Usage: ./run [options]

       Options:
         -h --help                 Print out this Usage info
         -l --linux                Run for linux
         -w --windows              (default) Run for windows
         -s --enable-tgsi          Enable the running of tgsi tests
         -o --enable-obfuscate     Do obfuscation tests
         -t --testfile <testfile>  Run on a single test file
         -r --release              Run with release build
         -v --verbose              Prints more info
"

# Add more tests here as they are created
TESTS=(test.frag               \
       flowControl.frag        \
	   deepRvalue.frag         \
       Operations.frag         \
	   length.frag             \
       swizzle.frag            \
       simpleFunctionCall.frag \
       functionCall.frag       \
       functionSemantics.frag  \
       voidFunction.frag       \
	   forLoop.frag            \
	   whileLoop.frag          \
       loops.frag              \
       loopsArtificial.frag    \
       earlyReturnDiscard.frag \
       discard-dce.frag        \
       always-discard.frag     \
       always-discard2.frag    \
       syntaxError.frag        \
       depthOut.frag           \
       dataOut.frag            \
       dataOutIndirect.frag    \
       dataOutIndirect.vert    \
       varyingArray.frag       \
       varyingArrayIndirect.frag \
       uniformArray.frag       \
       variableArrayIndex.frag \
       matrix.frag             \
       matrix2.frag            \
       newTexture.frag         \
       structure.frag          \
       structAssignment.frag   \
       structDeref.frag        \
       localAggregates.frag    \
	   aggOps.frag             \
       texture.frag            \
       texture.vert            \
       types.frag              \
       test.vert               \
       conditionalDiscard.frag \
       ps_shader.frag          \
       sw_shader.frag          \
      )

# $1 is the test
# Rest are options to the runcommand
function runSingleTest {
    $RUNCMD ${OPTIONS[@]} ${@:2:${#@}} $1 > temp.stdout 2> temp.errout
}

function printVerbose {
    if [ -n "$VERBOSE" ]
    then
        printf "$@"
    fi
}

function printVerboseNL {
    printVerbose "$@"
    printVerbose "\n"
}

function runTests {
    for t in ${TESTS[@]}; do
        printf "Running $t"
        if [ -z "$VERBOSE" ]
        then
            echo
        fi

        if [ -n "$VERBOSE" ]
        then
            LENSTR=$((${#t} + 8))
            INDENTLVL=$((37 - $LENSTR))
            OBFUSCATE_INDENTLVL=$(($INDENTLVL + 5))
            GLSLLVL=41 # Magic number
        fi

        if [ -n "$DO_TGSI" ]
        then
            # Run for TGSI
            printVerbose "%${INDENTLVL}s" "TGSI "
            runSingleTest $t $TGSI_OP && printVerbose "[OK]" \
                || (printVerboseNL "[FAIL] " ; tail -n 1 temp.errout ; printVerbose "%${GLSLLVL}s" " ")
            cat temp.errout temp.stdout > tgsi/$t.out.tmp
            tr -d '\r' < tgsi/$t.out.tmp > tgsi/$t.out

        else
            printVerbose "%${INDENTLVL}s" " "
            printVerbose "    "
        fi

        # Run for GLSL
        printVerbose "        GLSL "
        runSingleTest $t $GLSL_OP && printVerboseNL "[OK]" \
            || (printVerboseNL "[FAIL] " ; tail -n 1 temp.errout)
        cat temp.errout temp.stdout > glsl/$t.out.tmp
        tr -d '\r' < glsl/$t.out.tmp > glsl/$t.out
		rm glsl/$t.out.tmp

        if [ -n "$DO_OBFUSCATE" ]
        then
            printVerbose "    Obfuscating:                "

            if [ -n "$DO_TGSI" ]
            then
                # Run obfuscated TGSI
                printVerbose "TGSI "
                runSingleTest $t $TGSI_OP $OBFUSCATE_OP && printVerbose "[OK]" \
                    || (printVerboseNL "[FAIL] " ; tail -n 1 temp.errout ; printVerbose "%${GLSLLVL}s" " ")
                cat temp.errout temp.stdout > tgsi/$t.out.obfuscated
            else
                printVerbose "         "
            fi


            # Run obfuscated GLSL
            printVerbose "        GLSL "
            runSingleTest $t $GLSL_OP $OBFUSCATE_OP && printVerboseNL "[OK]" \
                || (printVerboseNL "[FAIL] " ; tail -n 1 temp.errout)
            cat temp.errout temp.stdout > glsl/$t.out.obfuscated
        fi

        printVerbose "    Feeding back in:                     "
        printVerbose "        GLSL "
        ($RUNCMD $GLSL_OP $t > temp.stdout.frag 2> temp.errout \
            && $RUNCMD $GLSL_OP temp.stdout.frag > temp.stdout 2> temp.errout && printVerboseNL "[OK]") \
            || (printVerboseNL "[FAIL] " ; tail -n 1 temp.errout)
        cat temp.stdout > glsl/$t.out.rerun

        if [ -n "$DO_OBFUSCATE" ]
        then
            printVerbose "    De-obfuscating:                      "
            printVerbose "        GLSL "
            ($RUNCMD $GLSL_OP $OBFUSCATE_OP $t > temp.stdout.obfuscated.frag 2> temp.errout \
                && $RUNCMD $GLSL_OP temp.stdout.obfuscated.frag > temp.stdout 2> temp.errout && printVerboseNL "[OK]") \
                || (printVerboseNL "[FAIL] " ; tail -n 1 temp.errout)
            cat temp.stdout > glsl/$t.out.de-obfuscated
        fi

    done
    rm temp.stdout* temp.errout
}

function showHelp {
    echo "$DESCRIPTION"
    echo "$USAGE"
}

# Default is for windows
RUNCMD=../Build/Debug/glsl2.exe
OPTIONS=(-d -n)
TGSI_OP="--tgsi"
GLSL_OP="--glsl"
OBFUSCATE_OP="-f"
DO_TGSI=""
DO_OBFUSCATE=""
VERBOSE=""

# Command-line argument Handling

# Arguments passed
while [ $# -gt 0 ]; do
    case "$1" in
        -l|--linux)
            RUNCMD=../Standalone/StandAlone
            ;;
        -h|--h)
            showHelp
            exit 0
            ;;
        -s|--enable-tgsi)
            DO_TGSI="true"
            ;;
        -t|--testfile)
            TESTS=("$2")
            if [ ! -e "$2" ]
            then
                echo "Error: testfile $2 not found"
                exit 1
            fi
            shift
            ;;
        -r|--release)
            RUNCMD=../Build/Release/glsl2.exe
            ;;
        -v|--verbose)
            VERBOSE="true"
            ;;
        -o|--do-obfuscate)
            DO_OBFUSCATE="true"
            ;;
        *)
            showHelp
            exit 1
            ;;
    esac
    shift
done

runTests
