#!/bin/sh

set -euf

# -----------------------------------------------------------------------------
# Basic fundamentals

prefix=@prefix@
exec_prefix=@exec_prefix@
datarootdir=@datarootdir@
datadir=@datadir@
sysconfdir=@sysconfdir@
libdir=@libdir@
privatedir=@privatedir@
with_trust_paths=@with_trust_paths@
script=$(basename $0)

# -----------------------------------------------------------------------------
# Testing

warning()
{
	echo "$script: $@" >&2
}

assert_fail()
{
	warning $@
	exit 1
}

assert_contains()
{
	if ! grep -qF $2 $1; then
		assert_fail "$1 does not contain $2"
	fi
}

assert_not_contains()
{
	if grep -qF $2 $1; then
		assert_fail "$1 contains $2"
	fi
}

teardown()
{
	for x in $TD; do
		if [ -d $x ]; then
			rmdir $x
		elif [ -f $x ]; then
			rm $x
		fi
	done
	TD=""
}

teardown_dirty()
{
	echo "not ok $TEST_NUMBER $TEST_NAME"
	teardown
}

openssl_quiet()
(
	command='/Generating a|-----|^[.+]+$|writing new private key/d'
	exec 3>&1
	openssl $@ 2>&1 >&3 3>&- | sed -r "$command" 3>&-
)

skip()
{
	TEST_SKIP=yes
	echo "ok $TEST_NUMBER # skip $TEST_NAME: $@"
}

setup()
{
	# Parse the trust paths
	oldifs="$IFS"
	IFS=:
	set $with_trust_paths
	IFS="$oldifs"

	if [ ! -d $1 ]; then
		skip "$1 is not a directory"
		return
	fi

	SOURCE_1=$1
	if [ $# -lt 2 ]; then
		warning "certain tests neutered if only 1 trust path: $with_trust_paths"
		SOURCE_2=$1
	else
		SOURCE_2=$2
	fi

	# Make a temporary directory
	dir=$(mktemp -d)
	cd $dir
	CLEANUP="$dir $TD"

	# Generate a unique identifier
	CERT_1_CN=test_$(dd if=/dev/urandom count=40 bs=1 status=none | base64 | tr -d '+/=')
	CERT_2_CN=test_$(dd if=/dev/urandom count=40 bs=1 status=none | base64 | tr -d '+/=')
	CERT_3_CN=test_$(dd if=/dev/urandom count=40 bs=1 status=none | base64 | tr -d '+/=')

	# Generate relevant certificates
	openssl_quiet req -x509 -newkey rsa:512 -keyout /dev/null -days 3 -nodes \
		-out cert_1.pem -subj /CN=$CERT_1_CN
	openssl_quiet req -x509 -newkey rsa:512 -keyout /dev/null -days 3 -nodes \
		-out cert_2.pem -subj /CN=$CERT_2_CN
	openssl_quiet req -x509 -newkey rsa:512 -keyout /dev/null -days 3 -nodes \
		-out cert_3.pem -subj /CN=$CERT_3_CN

	TD="cert_1.pem cert_2.pem cert_3.pem $TD"

	mkdir -p $SOURCE_1/anchors
	cp cert_1.pem $SOURCE_1/anchors/

	mkdir -p $SOURCE_2/anchors
	cp cert_2.pem $SOURCE_2/anchors/
	cp cert_3.pem $SOURCE_2/anchors/

	TD="$SOURCE_1/anchors/cert_1.pem $SOURCE_2/anchors/cert_2.pem $SOURCE_2/anchors/cert_3.pem $TD"
}

run()
{
	TOTAL=0
	for TEST_NAME in $@; do
		TOTAL=$(expr $TOTAL + 1)
	done

	echo "1..$TOTAL"

	TEST_NUMBER=0
	for TEST_NAME in $@; do
		TEST_NUMBER=$(expr $TEST_NUMBER + 1)
		(
			trap teardown_dirty EXIT
			trap "teardown_dirty; exit 127" INT TERM
			TD=""

			TEST_SKIP=no
			setup

			if [ $TEST_SKIP != "yes" ]; then
				$TEST_NAME
			fi
			if [ $TEST_SKIP != "yes" ]; then
				echo "ok $TEST_NUMBER $TEST_NAME"
			fi

			trap - EXIT
			teardown
		)
	done
}

# -----------------------------------------------------------------------------
# Main tests

test_extract()
{
	trust extract --filter=ca-anchors --format=pem-bundle \
		--purpose=server-auth --comment \
		extract-test.pem

	assert_contains extract-test.pem $CERT_1_CN
	assert_contains extract-test.pem $CERT_2_CN
	assert_contains extract-test.pem $CERT_3_CN
}

test_blacklist()
{
	mkdir -p $SOURCE_1/blacklist
	cp cert_3.pem $SOURCE_1/blacklist
	TD="$SOURCE_1/blacklist/cert_3.pem $TD"

	trust extract --filter=ca-anchors --format=pem-bundle \
		--purpose=server-auth --comment \
		blacklist-test.pem

	assert_contains blacklist-test.pem $CERT_1_CN
	assert_not_contains blacklist-test.pem $CERT_3_CN
}

run test_extract test_blacklist