#!/usr/bin/env bash
set -euo pipefail

build_root=$1
src=$2

cli_dir="$build_root/src/cli"
php2ast="$cli_dir/phpefc-php2ast"
phpast2phpir="$cli_dir/phpefc-phpast2phpir"
phpir2valair="$cli_dir/phpefc-phpir2valair"
valair2vala="$cli_dir/phpefc-valair2vala"
valair_optimize="$cli_dir/phpefc-valair-optimize-typing"

for tool in "$php2ast" "$phpast2phpir" "$phpir2valair" "$valair_optimize" "$valair2vala"; do
    if [ ! -x "$tool" ]; then
        echo "missing built tool: $tool" >&2
        exit 99
    fi
done

work=${MESON_TEST_TMPDIR:-}
if [ -z "$work" ]; then
    work=$(mktemp -d)
    trap 'rm -rf "$work"' EXIT
fi
mkdir -p "$work"

phpast="$work/throw_exception.phpast"
phpir="$work/throw_exception.phpir"
valair="$work/throw_exception.valair"
vala="$work/throw_exception.vala"

"$php2ast" "$src" "$phpast"
"$phpast2phpir" "$phpast" "$phpir"
"$phpir2valair" "$phpir" "$valair"
"$valair_optimize" "$valair" "$valair.afteropt.typing-zval2static"
"$valair2vala" "$valair.afteropt.typing-zval2static" "$vala"

if ! grep -Fq " Throw" "$phpir"; then
    echo "expected PHP-IR Throw statement" >&2
    cat "$phpir" >&2
    exit 1
fi

for expected in \
    'PhpefRuntimeCore.init(args);' \
    '        phpef_main();' \
    '        return 0;' \
    'public static void phpef_main() throws Error {' \
    'public static int main(string[] args) {' \
    'catch (Error e)' \
    'return PhpefRuntimeCore.handle_uncaught(e);' \
    'PhpefRuntimeCore.throw_exception_at("Exception", Zval.from_string("boom"), Zval.from_int(0),'
do
    if ! grep -Fq "$expected" "$vala"; then
        printf 'expected generated Vala to contain: %s\n' "$expected" >&2
        printf 'actual generated Vala:\n' >&2
        cat "$vala" >&2
        exit 1
    fi
done

if ! grep -Fq '"format": "phpefc-c-source-lines-v0"' "$vala" || ! grep -Fq '"phpLine": 2' "$vala" || ! grep -Fq "$src" "$vala"; then
    printf 'expected generated source map to carry PHP source file and line: %s:2\n' "$src" >&2
    cat "$vala" >&2
    exit 1
fi

if grep -Eq 'stderr\.printf\("PHP(FE|EF)? Fatal error' "$vala"; then
    printf 'generated throw code must not emit fatal-error output directly\n' >&2
    cat "$vala" >&2
    exit 1
fi

if ! grep -Fq "\"$src\", 2);" "$vala"; then
    printf 'expected generated throw_exception_at() to carry PHP source location: %s:2\n' "$src" >&2
    cat "$vala" >&2
    exit 1
fi

printf 'ok 1 - throw new Exception("boom") lowers to runtime exception wrapper with source-map metadata\n'
