#!/bin/bash

set -e

NODE_OPTIONS="--disable-proto=throw"

if [ -e debian/tests/pkg-js/enable_proto ]; then
	NODE_OPTIONS=""
fi
export NODE_OPTIONS

# depends on autopkgtest timeout instead of upstream that do not run on slow target
TAP_TIMEOUT=0
export TAP_TIMEOUT

function dolink() {
	DIR=$1
	for f in `ls $DIR/`; do
		if [ -d $f ]; then
			( cd $f; dolink $DIR/$f )
		else
			ln -s $DIR/$f 2>/dev/null || true
		fi
	done
}

MAKEFILES='^(?:(?:g(?:ulpfile\.(?:babel\.m?j|(?:t|m?j))|runt(?:file)?\.j)|(?:(?:rollup[\.\-].*|ava\.)config|karma\.conf)\.j)s|j(?:a(?:kefile(?:\.js)?|smine\.json)|est\.config\.js|sl\.node\.conf)|\.(?:babelrc(?:\.js(?:on)?)?|mocharc\.js(?:on)?)|(?:tsconfig.*|lerna)\.json|babel\.config\.js(?:on)?|(?:[cm]ake|docker)file)$'

pack="."
if [ -e debian/nodejs/main ]; then
	pack=`grep -E -v '^(.*#.*|)$' debian/nodejs/main`
	echo "# Found debian/nodejs/main, package.(json|yaml) is in $pack"
fi
if [ ! -e $pack ]; then
	pack=$(dpkg -L `grep ^Package: debian/control|head -n1|sed -e 's/.*: *//'`|grep -v node_modules|grep -E 'package.(yaml|json)'|head -n1|sed -e 's/\/package.(yaml|json)//')
fi
if [ ! -e $pack/package.json -a ! -e $pack/package.yaml ]; then
	echo "### Unable to find package.json, aborting"
	exit 77
fi

echo "# Using $pack/package.(json|yaml)"

PKG=`pkgjs-utils pjson $pack name`

if [ -e debian/tests/pkg-js/require-name ]; then
	REQUIRE_PKG=`cat debian/tests/pkg-js/require-name| head -1| sed 's/^ *//g'`
	if [ "$REQUIRE_PKG" = "" ]; then
		echo "# debian/tests/pkg-js/require-name exists but contains no valid name"
		exit 1
	fi
	echo "# debian/tests/pkg-js/require-name, module name will be: $REQUIRE_PKG"
else
	REQUIRE_PKG=$PKG
fi

echo "# Node module name is $REQUIRE_PKG"
LOCAL="0"

if [ -e debian/tests/pkg-js/SKIP ]; then
	SKIP_TEST=`cat debian/tests/pkg-js/SKIP| head -1| sed 's/^ *//g'`
	echo "# debian/tests/pkg-js/SKIP found, content: $SKIP_TEST"
fi

if test "$1" = "src"; then
	shift 1
	LOCAL=1
fi

COMMAND=$@
EVALCODE=0
function evalNode() {
	if "$@" 2>&1; then
		echo ok
		EVALCODE=0
	else
		echo not ok
		EVALCODE=1
	fi
}

function requireTest() {
	NAME=$1
	MPATH=`nodepath $NAME || true`
	if [ "$MPATH" == "" ]; then
		echo "#   Testing $NAME: NOT FOUND"
		EVALCODE=1
	else
		TYPE=`pkgjs-utils pjson $MPATH type`
		MAIN=`pkgjs-utils pjson $MPATH main`
		if [ "$MAIN" == "" ]; then
			MAIN=`pkgjs-utils pjson $MPATH exports|grep '"require"' || true`
		fi
		if [ "$TYPE" == "module" ]; then
			rm -rf node_modules
			echo "# /!\ Package is a ES module"
			DEPS=`pkgjs-utils pjson $MPATH dependencies|perl -000 -MJSON -lne '$a.=$_;END{if($a){$a=JSON::from_json($a);print $_ foreach(keys %$a)}}'`
			mkdir node_modules
			for dep in $DEPS $NAME; do
				if [ ! -e node_modules/$dep ]; then
					echo -n "#   Dependency $dep: "
					if nodepath $dep >/dev/null 2>&1; then
						MODDIR=`nodepath $dep`
						RELDIR=node_modules`dirname $MODDIR|sed -e 's/.*nodejs//'`
						mkdir -p $RELDIR
						if [ -e /usr/share/node_modules ]; then
							ln -s $MODDIR $RELDIR
							echo linked
						else
							cp -a $MODDIR $RELDIR
							echo copied
						fi
					else
						echo "skip copy, $dep not found"
					fi
				fi
			done
			echo '{"name": "foo","type": "module"}' > package.json
			echo "import TMP from '$NAME';console.log('Import succeeds')" > test.mjs
			echo -n "#   Testing $NAME: "
			evalNode node test.mjs
			if [ "$EVALCODE" != 0 ]; then
				echo -n "#   Testing $NAME without default export: "
				echo "import * as TMP from '$NAME';console.log('Import succeeds')" > test.mjs
				evalNode node test.mjs
			fi
			rm -rf node_modules package.json test.mjs
			if [[ "$MAIN" != "" && "$EVALCODE" != 0 ]]; then
				echo -n "#   Testing $NAME via require: "
				evalNode node --no-deprecation -e "require('$NAME')"
			fi
		elif [[ "$MAIN" != "" || -e `nodepath $NAME`/index.js ]]; then
			echo -n "#   Testing $NAME: "
			evalNode node --no-deprecation -e "require('$NAME')"
		else
			echo "#   Testing $NAME: SKIPPED"
			EVALCODE=0
			SKIP=77
		fi
	fi
}

if test "$COMMAND" = "require"; then
	echo "# Test: require"
	SKIP=0
	SKIP_MAIN=0
	if test "$SKIP_TEST" != "require"; then
		if [ -e debian/tests/pkg-js/require-SKIP ]; then
			ROOT_MODULE_LIST=`pkgjs-utils root_modules_list 2>/tmp/pkg-js.err | grep -v -x -f debian/tests/pkg-js/require-SKIP || true`
			if echo $REQUIRE_PKG | grep -v -x -f debian/tests/pkg-js/require-SKIP >/dev/null; then
				true
			else
				SKIP_MAIN=1
			fi
		else
			ROOT_MODULE_LIST=`pkgjs-utils root_modules_list 2>/tmp/pkg-js.err || true`
		fi
		cat /tmp/pkg-js.err
		rm -f /tmp/pkg-js.err
		cd ${AUTOPKGTEST_TMP:-${TMPDIR:-/tmp}}
		if [ "$SKIP_MAIN" != "1" ]; then
			requireTest $REQUIRE_PKG
		else
			echo "Skip test for $REQUIRE_PKG"
			SKIP=77
		fi
		MAINEVALCODE=$EVALCODE
		MAINSKIP=$SKIP
		for module in $ROOT_MODULE_LIST; do
			requireTest $module
			let MAINEVALCODE=MAINEVALCODE+EVALCODE || true
		done
		if [[ $MAINSKIP == 77 && $MAINEVALCODE == 0 ]]; then
			exit $MAINSKIP
		fi
		exit $MAINEVALCODE
	else
		echo '# Require Tests were NOT launched ...'
		exit 77
	fi
elif test "$SKIP_TEST" != "test"; then
	if test "$PKG" = ""; then
		PKG=$REQUIRE_PKG
	fi
	if test "$PKG" = ""; then
		echo "No Node package name found, try to set it in debian/tests/pkg-js/require-name"
		exit 1
	fi
	#MAKEFILES=`ls|perl -ne "chomp;print qq{\$_ } if /$MAKEFILES/i" || true`
	MAKEFILES=`ls -a|perl -ne "print if /$MAKEFILES/i"|xargs echo || true`
	echo "# Build files found: $MAKEFILES"
	TESTFILES=`ls -d test* fixture* tap-snapshots map.js 2>/dev/null || true`
	echo "# Test files found: $TESTFILES"
	TESTFILES="$TESTFILES $MAKEFILES"
	if [ -e debian/tests/pkg-js/files ]; then
		echo "# Found debian/tests/pkg-js/files, let's use it"
		TESTFILES=`cat debian/tests/pkg-js/files`
	fi
	echo "# Files/dir to be installed from source: $TESTFILES"

	TEST=debian/tests/pkg-js/test
	if [ ! -e $TEST ]; then
		echo "### Missing debian/tests/pkg-js/test file, skipping"
		exit 77
	fi
	if test "$LOCAL" = "0"; then
		TEMP=${AUTOPKGTEST_TMP:-${TMPDIR:-/tmp}}
		HOME=$TEMP
		export HOME
		TDIR=$(mktemp -d $TEMP/smokeXXXXXX)
		if test "$TESTFILES" != " "; then
			if ls -d $TESTFILES >/dev/null; then
				echo "# Copy test files"
				tar cf - $TESTFILES | tar xf - -C $TDIR
			fi
		else
			echo "# No test files to install"
		fi
		if [ -e debian/tests/pkg-js ]; then
			echo "# Copy debian/tests/pkg-js content"
			mkdir -p $TDIR/debian/tests/
			cp -av debian/tests/pkg-js $TDIR/debian/tests/
		fi
		if [ -d debian/tests/test_modules ]; then
			echo "Found debian/tests/test_modules"
			if [ ! -d $TDIR/debian/tests/test_modules ]; then
				echo "# let's copy it"
				mkdir -p debian/tests
				cp -a debian/tests/test_modules $TDIR/debian/tests/
			fi
			if [ ! -d $TDIR/node_modules ]; then
				mkdir $TDIR/node_modules
			fi
			if [ -w $TDIR/node_modules ]; then
				(cd $TDIR && pkgjs-utils link_test_modules)
			else
				echo "export NODE_PATH=debian/tests/test_modules:node_modules"
				export NODE_PATH=debian/tests/test_modules:node_modules
			fi
		fi
		if [ -d debian/build_modules ]; then
			echo "Found debian/build_modules"
			if [ ! -d $TDIR/debian/build_modules ]; then
				echo "# let's copy it"
				mkdir -p $TDIR/debian
				cp -a debian/build_modules $TDIR/debian/build_modules/
			fi
			if [ ! -d $TDIR/node_modules ]; then
				mkdir $TDIR/node_modules
			fi
			if [ -w $TDIR/node_modules ]; then
				(cd $TDIR && pkgjs-utils link_build_modules)
			fi
		fi
		if [ -e debian/nodejs/extlinks ]; then
			echo "Found debian/nodejs/extlinks"
			if [ ! -d $TDIR/node_modules ]; then
				mkdir $TDIR/node_modules
			fi
			if [ -w $TDIR/node_modules ]; then
				for mod in `cat debian/nodejs/extlinks|perl -pe 's/\s+.*$/ /'|grep -v '^#'`; do
					if nodepath $mod >/dev/null 2>&1; then
						( cd $TDIR; pkgjs-utils ln $mod 2>/dev/null || true)
					else
						echo "$mod not found, skipping link"
					fi
				done
			fi
		fi
		if [ -e debian/nodejs/extcopies ]; then
			echo "Found debian/nodejs/extcopies"
			if [ ! -d $TDIR/node_modules ]; then
				mkdir $TDIR/node_modules
			fi
			if [ -w $TDIR/node_modules ]; then
				for mod in `cat debian/nodejs/extcopies|perl -pe 's/\s+.*$/ /'|grep -v '^#'`; do
					if nodepath $mod >/dev/null 2>&1; then
						dir=`dirname $mod`
						mkdir -p "$TDIR/node_modules/$dir"
						echo cp -rL `nodepath "$mod"` "$TDIR/node_modules/$dir"
						cp -rL `nodepath "$mod"` "$TDIR/node_modules/$dir" || echo "Failed to copy $mod"
					else
						echo "$mod not found, skipping link"
					fi
				done
			fi
		fi
		for mod in `pkgjs-utils modules_list`; do
			if nodepath $mod >/dev/null 2>&1; then
				( cd $TDIR; pkgjs-utils ln $mod 2>/dev/null || true )
			fi
		done
		cd $TDIR
		for NPATH in /usr/lib/nodejs/$PKG /usr/lib/*/nodejs/$PKG /usr/share/nodejs/$PKG; do
			echo "# Searching module in $NPATH"
			if test -e $NPATH; then
				echo "# Found $NPATH"
				echo "# Searching files to link in $NPATH"
				dolink $NPATH
			fi
		done
	fi
	if test "$COMMAND" = ""; then
		echo "# Launch $TEST with sh -ex"
		sh -ex $TEST
	else
		echo "# Launch command: $COMMAND"
		$COMMAND
	fi
else
	echo '# No tests will be run ...'
	exit 77
fi
if test "$TDIR" != ""; then
	echo "# Cleaning tmp dir"
	rm -rf $TDIR
fi
