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

build_root=$1

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

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"

src="$work/microtime-typed-fast-paths.php"
phpast="$work/microtime-typed-fast-paths.phpast"
phpir="$work/microtime-typed-fast-paths.phpir"
valair="$work/microtime-typed-fast-paths.valair"
afteropt="$work/microtime-typed-fast-paths.valair.afteropt.typing-zval2static"
vala="$work/microtime-typed-fast-paths.vala"
stderr_file="$work/microtime-typed-fast-paths.stderr"

cat >"$src" <<'PHP'
<?php
microtime();
microtime(false);
microtime(true);
PHP

"$php2ast" "$src" "$phpast" >/dev/null
"$phpast2phpir" "$phpast" "$phpir" >/dev/null
"$phpir2valair" "$phpir" "$valair" >/dev/null
if ! "$valair_optimize" "$valair" "$afteropt" >/dev/null 2>"$stderr_file"; then
    echo "typing optimizer failed" >&2
    cat "$stderr_file" >&2
    exit 1
fi
if ! "$valair2vala" "$afteropt" "$vala" >/dev/null; then
    echo "valair2vala failed" >&2
    exit 1
fi

for expected_typed_call in \
    'PhpefRuntimeEmbed.phpfunc_microtime_typed_string();' \
    'PhpefRuntimeEmbed.phpfunc_microtime_typed_string_arg1_bool_false();' \
    'PhpefRuntimeEmbed.phpfunc_microtime_typed_double_arg1_bool_true();'
do
    if ! grep -Fq "$expected_typed_call" "$vala"; then
        echo "expected typed microtime fast path in generated Vala: $expected_typed_call" >&2
        cat "$vala" >&2
        exit 1
    fi
done

for expected_ir_callee in \
    'PhpefRuntimeEmbed.phpfunc_microtime_typed_string' \
    'PhpefRuntimeEmbed.phpfunc_microtime_typed_string_arg1_bool_false' \
    'PhpefRuntimeEmbed.phpfunc_microtime_typed_double_arg1_bool_true'
do
    if ! grep -a -Fq "$expected_ir_callee" "$afteropt"; then
        echo "expected typed microtime fast path callee in optimized ValaIR bundle: $expected_ir_callee" >&2
        exit 1
    fi
done

for forbidden_call in \
    'PhpefRuntimeEmbed.phpfunc_microtime();' \
    'PhpefRuntimeEmbed.phpfunc_microtime(Zval.from_bool(false));' \
    'PhpefRuntimeEmbed.phpfunc_microtime(Zval.from_bool(true));'
do
    if grep -Fq "$forbidden_call" "$vala"; then
        echo "generic Zval microtime call was not optimized away: $forbidden_call" >&2
        cat "$vala" >&2
        exit 1
    fi
done
