#!/bin/bash

set -e

lib="gfoidl.Base64.dll"
tfm="net7.0"
path="gfoidl.Base64.FuzzTests/bin/Release/$tfm"

"$path"/gfoidl.Base64.FuzzTests "PrintMachineInfo"

if [[ $# -lt 3 ]]; then
    echo "first  arg must be the fuzz type, either 'afl' or 'libFuzzer'"
    echo "second arg must be duration for timeout (in seconds)"
    echo "third  arg must be the fuzz-function"
    echo "  - Base64_Default_Decode"
    echo "  - Base64_Default_Decode_Whitespace"
    echo "  - Base64_Url_Decode"
    echo "  - Base64_Url_Decode_Whitespace"
    exit 1
fi

cp ./instrumented/$lib "$path"/
mkdir -p findings/crashes

fuzzType=$1
duration=$2
fuzzFunction=$3
shift 3

echo "running fuzz for $duration..."

case $fuzzType in
    "afl")
        timeout --preserve-status "$duration" afl-fuzz -i testcases -o findings -m 10000 -t 5000 "$path"/gfoidl.Base64.FuzzTests $fuzzFunction "$*"
        ;;
    "libFuzzer")
        # https://llvm.org/docs/LibFuzzer.html#options
        ./libfuzzer-dotnet                                  \
            --target_path="$path"/gfoidl.Base64.FuzzTests   \
            --target_arg=$fuzzFunction                      \
            -max_total_time=$duration                       \
            -print_final_stats=1                            \
            -print_pcs=1                                    \
            -artifact_prefix="./findings/crashes/"          \
            testcases
        ;;
esac

# when there are any reports in ./findings/crashes, so there are failures
if [[ $(ls ./findings/crashes | wc -l) -gt 0 ]]; then
    cd findings/crashes

    rename 's|:|-|g' ./*
    ls -la
    
    exit 1
fi
