#!/usr/bin/env atf-sh

. $(atf_get_srcdir)/test_env.sh
init_tests \
	abuild_fetch_help \
	abuild_fetch_curl_invocation \
	abuild_fetch_curl_failure \
	abuild_fetch_curl_http \
	abuild_fetch_wget_fallback \
	abuild_fetch_wget_failure \
	abuild_fetch_wget_http \
	abuild_fetch_locking

create_fake_curl() {
	mkdir bin
	# fake curl
	cat > bin/curl <<-EOF
		#!/bin/sh

		echo "[\$\$] Fake curl invoked with: \$@"
		if [ -n "\$STAMP" ]; then
			touch "\$STAMP"
		fi
		for fifo in \$FIFOS; do
			echo "[\$\$] waiting for fifo \$fifo"
			cat "\$fifo"
		done
		exit \${CURL_EXITCODE:-0}
	EOF
	chmod +x bin/curl
	PATH="$PWD/bin:$PATH"
}

create_fake_wget() {
	mkdir -p bin
	cat > bin/wget <<-EOF
		#!/bin/sh

		echo "Fake wget invoked with: \$@"
		exit \${WGET_EXITCODE:-0}
	EOF
	chmod +x bin/wget
}

abuild_fetch_help_body() {
	atf_check -s exit:0 \
		-o not-empty \
		-e empty \
		abuild-fetch -h
}

abuild_fetch_curl_invocation_body() {
	create_fake_curl
	atf_check -s exit:0 \
		-o match:"Fake curl invoked" \
		-e empty \
		abuild-fetch -d "$PWD" https://example.com/non-existing
}

abuild_fetch_curl_failure_body() {
	create_fake_curl
	# verify that fake curl works
	CURL_EXITCODE=1 atf_check -s exit:$CURL_EXITCODE \
		-o match:"Fake curl invoked" \
		curl
	CURL_EXITCODE=1 atf_check -s exit:$CURL_EXITCODE \
		-o match:"Fake curl invoked" \
		-e empty \
		abuild-fetch -d "$PWD" https://example.com/non-existing
}

abuild_fetch_curl_http_body() {
	create_fake_curl
	atf_check -s exit:0 \
		-o match:"--insecure" \
		-e empty \
		abuild-fetch -d "$PWD" http://example.com/non-existing
}

abuild_fetch_wget_fallback_body() {
	create_fake_wget
	PATH="$PWD/bin:$(atf_get_srcdir)/.." atf_check -s exit:0 \
		-o match:"Fake wget invoked" \
		-e empty \
		abuild-fetch -d "$PWD" https://example.com/non-existing
}

abuild_fetch_wget_failure_body() {
	create_fake_wget
	WGET_EXITCODE=1 PATH="$PWD/bin:$(atf_get_srcdir)/.." atf_check -s exit:1 \
		-o match:"Fake wget invoked" \
		-e empty \
		abuild-fetch -d "$PWD" https://example.com/non-existing
}

abuild_fetch_wget_http_body() {
	create_fake_wget
	PATH="$PWD/bin:$(atf_get_srcdir)/.." atf_check -s exit:0 \
		-o match:"--no-check-certificate" \
		-e empty \
		abuild-fetch -d "$PWD" http://example.com/non-existing
}

abuild_fetch_locking_body() {
	create_fake_curl
	mkfifo waitstart1 waitstart2 done1 done2

	cat > bin/test-locking <<-EOF
		#!/bin/sh

		# start first instance
		FIFOS="waitstart1 done1" CURL_EXITCODE=1 \
			abuild-fetch -d "$PWD" https://example.com/foo &
		pid1=\$!

		# block til curl is called so we dont start the second instance too early
		echo "block1" > waitstart1

		# try a second fetch, while the first one is still running
		FIFOS="waitstart2 done2" STAMP=stamp2 \
			abuild-fetch -d "$PWD" https://example.com/foo &
		pid2=\$!

		# second instance should not start curl until first exits, so stamp2 should
		# not exist yet
		if [ -e stamp2 ]; then
			echo "stamp2 should not exist here" >&2
			exit 1
		fi

		# tell fake curl to similuate download fail of first instance
		echo "download 1 failed" > done1
		! wait \$pid1

		# wait til second instance gets lock to simulate download start
		echo "block2" > waitstart2

		# retry first download. second instance should block us
		FIFOS="done1" STAMP=stamp3 \
			abuild-fetch -d "$PWD" https://example.com/foo &
		pid1=\$!

		# give enough time for abuild-fetch to call curl
		sleep 0.5

		# the first stamp should not exist, second instance should block the retry
		if [ -e stamp3 ]; then
			echo "stamp3 should not exist here" >&2
			exit 1
		fi

		# simulate second download finished
		echo "download 2 complete" > done2
		wait \$pid2

		# first should get unblocked
		echo "download 3 complete" > done1
		wait \$pid1

		if ! [ -e stamp3 ]; then
			echo "stamp3 should exist here" >&2
			exit 1
		fi
	EOF

	atf_check -s exit:0 \
		-o match:"block1" \
		-o match:"download 1 failed" \
		-o match:"block2" \
		-o match:"download 2 complete" \
		-o match:"download 3 complete" \
		sh -e bin/test-locking

}

