#!/usr/bin/env bash

# SPDX-FileCopyrightText: 2021 - 2023 Robin Vobruba <hoijui.quaero@gmail.com>
#
# SPDX-License-Identifier: Unlicense

# Exit immediately on each error and unset variable;
# see: https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/
set -Eeuo pipefail
#set -Eeu

# initial default values
APP_NAME="Rust project test script"
debug=false

function print_help() {

	local script_name="$(basename "$0")"
	echo "$APP_NAME -"
	echo "We run all tests, even if some are failing."
	echo
	echo "Usage:"
	echo "  $script_name [OPTION...]"
	echo "Options:"
	echo "  -h, --help"
	echo "    Show this help message and exit"
	echo "  -d, --debug"
	echo "    Shows stdout for doc-test (and maybe more in the future)"
	echo "Examples:"
	echo "  $script_name"
	echo "  $script_name --debug"
}

# read command-line args
POSITIONAL=()
while [[ $# -gt 0 ]]
do
	arg="$1"
	shift # $2 -> $1, $3 -> $2, ...

	case "$arg" in
		-h|--help)
			print_help
			exit 0
			;;
		-d|--debug)
			debug=true
			;;
		*) # non-/unknown option
			POSITIONAL+=("$arg") # save it in an array for later
			;;
	esac
done
set -- "${POSITIONAL[@]}" # restore positional parameters


tests=0
failures=0

function _report_test_res() {
  res="$1"
  echo -n "TEST: "
  if [ "$res" -eq 0 ]
  then
    echo "succeeded."
  else
    echo "failed."
  fi
}

echo
echo
echo "TEST: 'cargo test' - Run unit-tests ..."
failed=0
cargo test --release || failed=1
failures=$((failures + failed))
tests=$((tests + 1))
_report_test_res "$failed"

echo
echo
echo "TEST: 'cargo fmt' - Check source code formatting ..."
failed=0
cargo fmt -- --check || failed=1
failures=$((failures + failed))
tests=$((tests + 1))
_report_test_res "$failed"

# `cargo sort` is not as readily available as other commands,
# thus we make this test optional
if cargo --list | grep "^\\s\+sort\(\\s\|\$\)" -q
then
echo
echo
echo "TEST: 'cargo sort' - Check Cargo.toml dependencies order ..."
failed=0
cargo sort --check || failed=1
failures=$((failures + failed))
tests=$((tests + 1))
_report_test_res "$failed"
fi

echo
echo
echo "TEST: 'cargo clippy' - Static code linting ..."
failed=0
cargo clippy --release -- \
  || failed=1
failures=$((failures + failed))
tests=$((tests + 1))
_report_test_res "$failed"

echo
echo
echo "TEST: 'cargo doc-code(-tests)' - Building documentaiton and running docu code ..."
# This flag will run your code examples as tests.
# For more, see the chapter on documentation tests:
# https://doc.rust-lang.org/rustdoc/documentation-tests.html
failed=0
if $debug
then
  cargo test --release --doc -- --show-output || failed=1
else
  cargo test --release --doc || failed=1
fi
failures=$((failures + failed))
tests=$((tests + 1))
_report_test_res "$failed"

echo
echo
echo "TEST: 'REUSE' - Licensing meta-data check ..."
if which reuse > /dev/null
then
  failed=0
  reuse lint || failed=1
  failures=$((failures + failed))
  tests=$((tests + 1))
  _report_test_res "$failed"
else
  >&2 echo "WARNING: REUSE tool not found; skipping licensing meta-data check."
fi

echo
echo
echo "Successful tests: $((tests - failures))/$tests"
if [ $failures -eq 0 ]
then
  echo "All tests successfull!"
else
  >&2 echo "There were test failures!"
fi

exit $failures
