#!/bin/bash
# Uses the TAP format, see https://testanything.org/tap-specification.html
# Run with -v to see output from the tests
set -e

function match {
	python3 -c '
import re, subprocess, sys

template = sys.stdin.read()

def resolve_sha(m):
    r = subprocess.run(["git", "rev-parse", m.group(1)],
                       capture_output=True, text=True)
    return r.stdout.strip()

pattern = re.sub(r"%sha\[([^\]]+)\]", resolve_sha, template)

KEYWORDS = {
    "%short": r"[0-9a-f]{12}",
    "%date": (r"[A-Z][a-z]{2} [A-Z][a-z]{2} {1,2}\d{1,2}"
              r" \d{2}:\d{2}:\d{2} \d{4} [+-]\d{4}"),
    "%sha": r"[0-9a-f]{40}",
}

parts = re.split(r"(%short|%date|%sha)", pattern)
regex = ""
for part in parts:
    if part in KEYWORDS:
        regex += KEYWORDS[part]
    else:
        regex += re.escape(part)

result = subprocess.run(["git", "show"],
                        capture_output=True, text=True).stdout

if re.fullmatch(regex, result):
    sys.exit(0)
print("------------ Expected: ------------")
print(template, end="")
print("-------------- Got: ---------------")
print(result, end="")
print("------------------------------------")
sys.exit(1)
'
}
export -f match

function patchpal {
	"$patchpal_bin" --test-case "$@"
}
export -f patchpal

function silence {
	"$@" &> /dev/null
}

function diagnostics {
	"$@" 2>&1 | { while IFS= read -r line; do echo "# $line"; done }
	return ${PIPESTATUS[0]}
}

self=$(readlink -f "$0")
export include=${self%/*}
cd "$include"
export patchpal_bin=$(readlink -f "$include"/../target/release/patchpal)
dir=$(mktemp --tmpdir -d patchpalgit.XXXXXXXXXX)
trap 'rm -rf "$dir"' EXIT
export repository="$dir/upstream"
export GIT_CONFIG_GLOBAL=/dev/null
export GIT_CONFIG_SYSTEM=/dev/null
unset GIT_COMMITTER_NAME
unset GIT_COMMITTER_EMAIL
unset GIT_AUTHOR_NAME
unset GIT_AUTHOR_EMAIL

tests=(test_*.sh)
tests_arg=""
output=silence
while getopts "b:t:v" opt; do
	case $opt in
		b) export patchpal_bin="$OPTARG" ;;
		t) tests_arg="$OPTARG" ;;
		v) output=diagnostics ;;
		\?) echo "Invalid option: -$OPTARG" >&2; exit 1 ;;
		:) echo "Option -$OPTARG requires an argument." >&2; exit 1 ;;
	esac
done

shift $((OPTIND - 1))

if [[ ! -z $tests_arg ]]; then
	tests=($tests_arg)
fi

count=0
for script in "${tests[@]}"; do
	count=$((count + 1))
	mkdir "$repository"
	git -C "$repository" -c 'init.defaultBranch=main' init > /dev/null
	git -C "$repository" config --local user.name "A Developer"
	git -C "$repository" config --local user.email "developer@example.com"
	git -C "$repository" config --local advice.detachedHead false
	git -C "$repository" config --local core.abbrev 12
	git -C "$repository" config --local diff.renames true
	cd "$repository"
	if $output bash -e "$include/$script"; then
		echo "ok $count $script"
	else
		echo "not ok $count $script"
	fi
	cd "$include"
	rm -rf "$dir"/*
done
echo "1..$count"
