#!/usr/bin/env -S bats --report-formatter junit --formatter tap -j 8
# -*-sh-*-
# shellcheck disable=SC2030,SC2031

load ../common/test_helper_functions

setup_file() {
	TESTNAME="modules"

	export TESTNAME
}

setup() {
	OUTPUT="$(mktemp)"

	export OUTPUT
}

teardown() {
	rm -f "${OUTPUT}"
}

@test "[${TESTNAME}] module purge" {
	run module purge
	assert_success
}

@test "[${TESTNAME}] module list" {
	module purge || exit 1
	run module list
	assert_success
	assert_output "No modules loaded"
}

@test "[${TESTNAME}] module help" {
	module purge || exit 1
	export MODULEPATH=./example-modules:"${MODULEPATH}"
	module help test-module &>"${OUTPUT}" || exit 1
	local my_output
	my_output=$(sed '/^$/d' "${OUTPUT}" | tail -1)
	assert_equal "Help message from test module" "${my_output}"
}

@test "[${TESTNAME}] module load/unload" {
	module purge || exit 1
	export MODULEPATH=./example-modules:"${MODULEPATH}"

	# verify env variable is not set prior to load
	if [ -n "${TEST_MODULE}" ]; then
		exit 1
	fi

	# load test-module and verify load works
	module load test-module || exit 1
	module list &>"${OUTPUT}" || exit 1
	grep -q '1) test-module' "${OUTPUT}" || flunk "test-module not loaded"

	# verify env variable was added correctly
	assert_equal "beeblebrox" "${TEST_MODULE}"

	# reload same module and verify no error
	run module load test-module
	assert_success

	# verify load of non-existent module generates error
	run module load test-module-it-should-no-workie
	assert_failure

	# remove test-module and verify
	module unload test-module || exit 1
	run module list
	assert_success
	assert_output "No modules loaded"

	# verify environment variable was removed
	[ -z "${TEST_MODULE}" ]
	assert_success
}

@test "[${TESTNAME}] module whatis" {
	module purge || exit 1
	export MODULEPATH=./example-modules:"${MODULEPATH}"
	module whatis test-module &>"${OUTPUT}" || exit 1
	local my_output
	my_output=$(sed '/^$/d; s/ \+//; s/ *$//' "${OUTPUT}")
	assert_equal "test-module: whatis: test-module" "${my_output}"
}

@test "[${TESTNAME}] module swap" {
	module purge || exit 1
	export MODULEPATH=./example-modules:"${MODULEPATH}"
	module load test-module || exit 1

	# verify family conflict
	run module load test2-module
	assert_failure

	module swap test-module test2-module || exit 1

	# verify correct env variable loaded after swap
	assert_equal "zaphod" "${TEST_MODULE}"

	# swap back and verify env variable
	module swap test2-module test-module || exit 1
	assert_equal "beeblebrox" "${TEST_MODULE}"
}

@test "[${TESTNAME}] path updated" {
	module purge || exit 1
	export MODULEPATH=./example-modules:"${MODULEPATH}"
	local orig_path="${PATH}"

	if [ -z "${MANPATH}" ]; then
		export MANPATH="/foo"
	fi

	local orig_manpath="${MANPATH}"

	# verify path after module load
	module load test-module || exit 1
	assert_equal "/my/test-module-path:${orig_path}" "${PATH}"

	# verify path after load of same module
	module load test-module || exit 1
	assert_equal "/my/test-module-path:${orig_path}" "${PATH}"

	# verify path after swap to new module
	module swap test-module test2-module || exit 1
	assert_equal "/my/test2-module-path:${orig_path}" "${PATH}"
	if [[ "${MANPATH}" != *"${orig_manpath}"* ]]; then
		flunk "${orig_manpath} missing from MANPATH"
	fi
	if [[ "${MANPATH}" != *"/my/test2-manpath"* ]]; then
		flunk "/my/test2-manpath missing from MANPATH"
	fi

	# verify path after addition of a new module
	module load test3-module || exit 1
	assert_equal "/my/test3-module-path:/my/test2-module-path:${orig_path}" "${PATH}"
	if [[ "${MANPATH}" != *"${orig_manpath}"* ]]; then
		flunk "${orig_manpath} missing from MANPATH"
	fi
	if [[ "${MANPATH}" != *"/my/test2-manpath"* ]]; then
		flunk "/my/test2-manpath missing from MANPATH"
	fi
	if [[ "${MANPATH}" != *"/my/test3-manpath"* ]]; then
		flunk "/my/test3-manpath missing from MANPATH"
	fi

	# verify path after removal of test modules
	module delete test2-module || exit 1
	assert_equal "/my/test3-module-path:${orig_path}" "${PATH}"
	module remove test3-module || exit 1
	assert_equal "${orig_path}" "${PATH}"
	assert_equal "${orig_manpath}" "${MANPATH}"
}

@test "[${TESTNAME}] module depends-on" {
	module purge || exit 1
	export MODULEPATH=./example-modules:"${MODULEPATH}"

	# verify dependent load
	module load test4-module || exit 1
	module list &>"${OUTPUT}" || exit 1
	grep -q '1) test3-module' "${OUTPUT}" || flunk "test3-module not loaded as dependency"
	grep -q '2) test4-module' "${OUTPUT}" || flunk "test4-module not loaded"

	# verify dependent unload
	module unload test4-module || exit 1
	run module list
	assert_success
	assert_output "No modules loaded"
}
