#!/usr/bin/env bash

set -e
set -u

# Author: w0rp <devw0rp@gmail.com>
#
# This script runs tests for the ALE project. The following options are
# accepted:
#
#            -v  Enable verbose output
# --neovim-only  Run tests only for NeoVim
#    --vim-only  Run tests only for Vim

current_image_id=d5a1b5915b09
image=w0rp/ale

tests='test/*.vader test/*/*.vader test/*/*/*.vader test/*/*/*.vader'
# These flags are forwarded to the script for running Vader tests.
verbose_flag=''
quiet_flag=''
run_neovim_tests=1
run_vim_tests=1
run_vint=1
run_custom_checks=1

while [ $# -ne 0 ]; do
    case $1 in
    -v)
        verbose_flag='-v'
        shift
    ;;
    -q)
        quiet_flag='-q'
        shift
    ;;
    --neovim-only)
        run_vim_tests=0
        run_vint=0
        run_custom_checks=0
        shift
    ;;
    --vim-only)
        run_neovim_tests=0
        run_vint=0
        run_custom_checks=0
        shift
    ;;
    --no-vint)
        run_vint=0
        shift
    ;;
    --vint-only)
        run_vim_tests=0
        run_neovim_tests=0
        run_custom_checks=0
        shift
    ;;
    --no-custom-checks)
        run_custom_checks=0
        shift
    ;;
    --custom-checks-only)
        run_vim_tests=0
        run_neovim_tests=0
        run_vint=0
        shift
    ;;
    --)
        shift
        break
    ;;
    -?*)
        echo "Invalid argument: $1" 1>&2
        exit 1
    ;;
    *)
        break
    ;;
    esac
done

# Allow tests to be passed as arguments.
if [ $# -ne 0 ]; then
    # This doesn't perfectly handle work splitting, but none of our files
    # have spaces in the names.
    tests="$*"
fi

# Delete .swp files in the test directory, which cause Vim 8 to hang.
find test -name '*.swp' -delete

docker images -q w0rp/ale | grep "^$current_image_id" > /dev/null \
    || docker pull "$image"

output_dir=$(mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir')

trap '{ rm -rf "$output_dir"; }' EXIT

file_number=0
pid_list=''

for vim in $(docker run --rm "$image" ls /vim-build/bin | grep '^neovim\|^vim' ); do
    if ((run_vim_tests)) || [[ $vim =~ ^neovim ]] && ((run_neovim_tests)); then
        echo "Starting Vim: $vim..."
        file_number=$((file_number+1))
        test/script/run-vader-tests $quiet_flag $verbose_flag "$vim" "$tests" \
            > "$output_dir/$file_number" 2>&1 &
        pid_list="$pid_list $!"
    fi
done

if ((run_vint)); then
    echo "Starting Vint..."
    file_number=$((file_number+1))
    test/script/run-vint > "$output_dir/$file_number" 2>&1 &
    pid_list="$pid_list $!"
fi

if ((run_custom_checks)); then
    echo "Starting Custom checks..."
    file_number=$((file_number+1))
    test/script/custom-checks &> "$output_dir/$file_number" 2>&1 &
    pid_list="$pid_list $!"
fi

echo

failed=0
index=0

for pid in $pid_list; do
    index=$((index+1))

    if ! wait "$pid"; then
        failed=1
    fi

    cat "$output_dir/$index"
done

exit $failed