#!/usr/bin/env bash
#
# Runs a single test against LinkedIn DustJS and duster to compare the result
set -euo pipefail
IFS=$'\n\t'
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

test_group=""
test_mode=""

function show_help {
    cat<<EOF
Runs a single test from the compliance test suite.

Usage: run_single_test.bash [options] <path_to_test_folder>

Options:
  --show-diff     Shows the difference between the two dust implementations
  --dustjs        Print the output of dustjs instead of comparing
  --duster        Print the output of duster instead of comparing
EOF
}

while (( "$#" )); do
    if [ "$1" = "--help" ]; then
        show_help
        exit 0
    elif [ "$1" = "--show-diff" ]; then
        show_diff=1
    elif [ "$1" = "--dustjs" ]; then
        test_mode="dustjs"
    elif [ "$1" = "--duster" ]; then
        test_mode="duster"
    elif [ ! "$1" = -* ]; then
        test_group="$1"
    else
        (>&2 echo "Unrecognized option: $1")
        exit 1
    fi
    shift
done

# Assert a test group was specified
if [ "$test_group" = "" ]; then
    show_help
    exit 1
fi

failed_count=0
test_group_name=$(basename "$test_group")
while read -r test_case; do
    test_case_file_name=$(basename "$test_case")
    test_case_name=${test_case_file_name%.*}
    set +e
    if [ "$test_mode" = "dustjs" ] || [ "$test_mode" = "" ]; then
        dustjs_output=$(xargs -a <(find "$test_group" -maxdepth 1 -mindepth 1 -type f -name 'main.dust'; find "$test_group" -maxdepth 1 -mindepth 1 -type f -name '*.dust' ! -name 'main.dust' | sort) node "$DIR/dustjs_shim.js" < "$test_case")
    fi
    if [ "$test_mode" = "duster" ] || [ "$test_mode" = "" ]; then
        duster_output=$(xargs -a <(find "$test_group" -maxdepth 1 -mindepth 1 -type f -name 'main.dust'; find "$test_group" -maxdepth 1 -mindepth 1 -type f -name '*.dust' ! -name 'main.dust' | sort) "$DIR/../target/debug/duster-cli" < "$test_case")
    fi

    if [ "$test_mode" = "dustjs" ]; then
        cat <<<"$dustjs_output"
    elif [ "$test_mode" = "duster" ]; then
        cat <<<"$duster_output"
    else
        (
            if cmp -s <(cat <<<"$dustjs_output") <(cat <<<"$duster_output"); then
                echo "$test_group_name::$test_case_name PASSED"
            else
                echo "$test_group_name::$test_case_name FAILED"
                if [ $show_diff -eq 1 ]; then
                    diff --label "dustjs-linkedin" --label "duster" <(cat <<<"$dustjs_output") <(cat <<<"$duster_output")
                fi
                exit 1
            fi
        )
        if [ $? -ne 0 ]; then
            failed_count=$((failed_count + 1))
        fi
    fi
    set -e
done <<<"$(find "$test_group" -maxdepth 1 -mindepth 1 -type f -name '*.json' | sort)"

exit "$failed_count"