#!/usr/bin/env bash

set -e
set -u

docker_flags=(--rm -v "$PWD:/testplugin" -v "$PWD/test:/home" -w /testplugin "$DOCKER_RUN_IMAGE")
red='\033[0;31m'
green='\033[0;32m'
nc='\033[0m'
verbose=0
quiet=0

while [ $# -ne 0 ]; do
    case $1 in
    -v)
        verbose=1
        shift
    ;;
    -q)
        quiet=1
        shift
    ;;
    --)
        shift
        break
    ;;
    -?*)
        echo "Invalid argument: $1" 1>&2
        exit 1
    ;;
    *)
        break
    ;;
    esac
done

vim="$1"
tests="$2"

echo "$vim"

case $vim in
    # Neovim 0.6+ requires headless argument to load Vader tests.
    neovim*)
        headless='--headless'
    ;;
    *)
        headless=''
    ;;
esac

# This file will be used to track if tests ran or not.
# We can't use a variable, because we need to set a value in a sub-shell.
run_file="$(mktemp -t tests_ran.XXXXXXXX)"

function filter-vader-output() {
    local hit_first_vader_line=0
    # When verbose mode is off, suppress output until Vader starts.
    local start_output="$verbose"
    local filtered_data=''

    while read -r; do
        # Search for the first Vader output line.
        # We can try starting tests again if they don't start.
        if ((!hit_first_vader_line)); then
            if [[ "$REPLY" = *'Starting Vader:'* ]]; then
                hit_first_vader_line=1
            fi
        fi

        if ((!start_output)); then
            if ((hit_first_vader_line)); then
                start_output=1
            else
                continue
            fi
        fi

        if ((quiet)); then
            if [[ "$REPLY" = *'Starting Vader:'* ]]; then
                filtered_data="$REPLY"
            elif [[ "$REPLY" = *'Success/Total'* ]]; then
                success="$(echo -n "$REPLY" | grep -o '[0-9]\+/' | head -n1 | cut -d/ -f1)"
                total="$(echo -n "$REPLY" | grep -o '/[0-9]\+' | head -n1 | cut -d/ -f2)"

                if [ "$success" -lt "$total" ]; then
                    echo "$filtered_data"
                    echo "$REPLY"
                fi

                filtered_data=''
            else
                filtered_data="$filtered_data"$'\n'"$REPLY"
            fi
        else
            echo "$REPLY"
        fi
    done

    # Note that we managed to get the Vader tests started if we did.
    if ((hit_first_vader_line)); then
        echo 1 > "$run_file"
    fi
}

function color-vader-output() {
    while read -r; do
        if [[ "$REPLY" = *'[EXECUTE] (X)'* ]]; then
            echo -en "$red"
        elif [[ "$REPLY" = *'[EXECUTE]'* ]] || [[ "$REPLY" = *'[  GIVEN]'* ]]; then
            echo -en "$nc"
        fi

        if [[ "$REPLY" = *'Success/Total'* ]]; then
            success="$(echo -n "$REPLY" | grep -o '[0-9]\+/' | head -n1 | cut -d/ -f1)"
            total="$(echo -n "$REPLY" | grep -o '/[0-9]\+' | head -n1 | cut -d/ -f2)"

            if [ "$success" -lt "$total" ]; then
                echo -en "$red"
            else
                echo -en "$green"
            fi

            echo "$REPLY"
            echo -en "$nc"
        else
            echo "$REPLY"
        fi
    done

    echo -en "$nc"
}

echo
echo '========================================'
echo "Running tests for $vim"
echo '========================================'
echo

tries=0

while [ "$tries" -lt 5 ]; do
    tries=$((tries + 1))

    exit_code=0
    set -o pipefail
    # shellcheck disable=SC2086
    "$DOCKER" run -a stderr -e VADER_OUTPUT_FILE=/dev/stderr "${docker_flags[@]}" \
        "/vim-build/bin/$vim" -u test/vimrc ${headless} \
        "+Vader! $tests" 2>&1 | filter-vader-output | color-vader-output || exit_code=$?
    set +o pipefail

    if [ -s "$run_file" ]; then
        break
    fi
done

if [ "$tries" -gt 1 ]; then
    echo
    echo "Tried to run tests $tries times"
fi

rm "$run_file"

exit "$exit_code"
