#!/bin/sh

# Copyright (C) 2017, 2018, 2019 Karl Landstrom <karl@miasap.se>
#
# This file is part of OBNC.
#
# OBNC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OBNC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with OBNC.  If not, see <http://www.gnu.org/licenses/>.

set -o errexit -o nounset

readonly selfDirPath="$(cd "$(dirname "$0")"; pwd -P)"
readonly packagePath="$(dirname "$selfDirPath")"
export OBNC_PREFIX="$packagePath"
export OBNC_LIBDIR="lib"
export CC="${CC:-}"
export CFLAGS="${CFLAGS:-} -I$packagePath/lib"

EchoAndRun()
{
	echo "$@"
	eval "$@"
}


CleanUp()
{
	find "$packagePath/tests/obnc" -name .obnc -type d | while read -r dir; do
		rm -r "$dir"
	done
	find "$packagePath/tests/obnc" -name "*.obn" -type f | while read -r file; do
		rm -f "${file%.obn}" "${file%.obn}.exe"
	done
}

CleanUp

dir="$packagePath/tests/obnc/passing"
EchoAndRun cd "$dir"
for module in *.obn; do
	if [ "$module" != T5SystemStatements.obn ]; then
		if EchoAndRun "OBNC_IMPORT_PATH='a dir' $packagePath/bin/obnc" "$module"; then
			if ! EchoAndRun "./${module%.obn}"; then
				printf "\nPositive test failed: %s\n\n" "$dir/$module">&2
				exit 1
			fi
		else
			printf "\nPositive test failed: %s\n\n" "$dir/$module" >&2
			exit 1
		fi
	fi
done

for def in OBNC_CONFIG_C_INT_TYPE=OBNC_CONFIG_SHORT \
		OBNC_CONFIG_C_INT_TYPE=OBNC_CONFIG_INT \
		OBNC_CONFIG_C_INT_TYPE=OBNC_CONFIG_LONG \
		OBNC_CONFIG_C_REAL_TYPE=OBNC_CONFIG_FLOAT \
		OBNC_CONFIG_C_REAL_TYPE=OBNC_CONFIG_DOUBLE \
		OBNC_CONFIG_C_REAL_TYPE=OBNC_CONFIG_LONG_DOUBLE \
		 OBNC_CONFIG_TARGET_EMB=1; do
	if EchoAndRun "CFLAGS='$CFLAGS -D $def' '$packagePath/bin/obnc'" -x A.obn; then
		if ! EchoAndRun ./A; then
			printf "\nPositive test compiled with C flag %s failed: %s\n\n" "$cFlag" "$dir/A.obn">&2
			exit 1
		fi
	else
		printf "\nPositive test compiled with C flag %s failed: %s\n\n" "$cFlag" "$dir/A.obn" >&2
		exit 1
	fi
done

dir="$packagePath/tests/obnc/failing-at-compile-time"
EchoAndRun cd "$dir"
for module in *.obn; do
	if [ "$module" != A.obn ] && [ "$module" != B.obn ]; then
		echo "$packagePath/bin/obnc-compile" "$module"
		if "$packagePath/bin/obnc-compile" "$module" 2>/dev/null; then
			printf "\nNegative test failed: %s\n\n" "$dir/$module" >&2
			exit 1
		elif [ "$?" -ne 1 ]; then
			printf "\nNegative test crashed: %s\n\n" "$dir/$module" >&2
			exit 1
		fi
	fi
done

dir="$packagePath/tests/obnc/failing-at-runtime"
EchoAndRun cd "$dir"
for module in *.obn; do
	if [ "$module" != A.obn ] && [ "$module" != B.obn ]; then
		if EchoAndRun "$packagePath/bin/obnc" "$module"; then
			echo "./${module%.obn}"
			if ( "./${module%.obn}" || false ) >/dev/null 2>&1; then
				printf "\nNegative test failed: %s\n\n" "$dir/$module" >&2
				exit 1
			fi
		else
			printf "\nNegative test failed: %s\n\n" "$dir/$module" >&2
			exit 1
		fi
	fi
done

CleanUp
