#!/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"
valair_optimize="$cli_dir/phpefc-valair-optimize-typing"
valair_optimize_typing="$cli_dir/phpefc-valair-optimize-typing"
valair_optimize_library="$cli_dir/phpefc-valair-optimize-library"
valair2vala="$cli_dir/phpefc-valair2vala"

for tool in "$php2ast" "$phpast2phpir" "$phpir2valair" "$valair_optimize" "$valair_optimize_typing" "$valair_optimize_library" "$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/optimizer-marker.phpast"
phpir="$work/optimizer-marker.phpir"
valair="$work/optimizer-marker.valair"
afteropt="$work/optimizer-marker.valair.afteropt.typing-zval2static"
library_afteropt="$work/optimizer-marker.valair.afteropt.library-embed2native"
vala="$work/optimizer-marker.vala"
typing_stderr="$work/optimizer-marker.typing.stderr"
library_stderr="$work/optimizer-marker.library.stderr"
marker_regex='// phpefc optimizer typing-zval2static result: [0-9]+/[0-9]+ zvals left'
library_marker_regex='// phpefc optimizer library-embed2native result: [0-9]+/[0-9]+ embed libphp\.so calls left( \([A-Za-z0-9_,() ]+\))?'

"$php2ast" "$src" "$phpast" >/dev/null
"$phpast2phpir" "$phpast" "$phpir" >/dev/null
"$phpir2valair" "$phpir" "$valair" >/dev/null
"$valair_optimize_typing" "$valair" "$afteropt" >/dev/null 2>"$typing_stderr"
"$valair_optimize_library" "$afteropt" "$library_afteropt" >/dev/null 2>"$library_stderr"
"$valair2vala" "$library_afteropt" "$vala" >/dev/null

if [ ! -f "$afteropt" ]; then
    echo "expected optimizer output $afteropt" >&2
    exit 1
fi
if [ ! -f "$library_afteropt" ]; then
    echo "expected optimizer output $library_afteropt" >&2
    exit 1
fi
if ! grep -a -Eq "$marker_regex" "$afteropt"; then
    echo "optimized ValaIR bundle misses typing optimizer marker" >&2
    cat "$afteropt" >&2
    exit 1
fi
if ! grep -a -Eq "$marker_regex" "$library_afteropt" || ! grep -a -Eq "$library_marker_regex" "$library_afteropt"; then
    echo "optimized ValaIR bundle misses chained optimizer markers" >&2
    cat "$library_afteropt" >&2
    exit 1
fi
if ! grep -Eq "$marker_regex" "$vala" || ! grep -Eq "$library_marker_regex" "$vala"; then
    echo "generated Vala misses optimizer marker comments" >&2
    cat "$vala" >&2
    exit 1
fi
if grep -a -q $'\033' "$afteropt" || grep -a -q $'\033' "$library_afteropt" || grep -q $'\033' "$vala"; then
    echo "optimizer marker comments must not contain ANSI escape codes" >&2
    cat "$vala" >&2
    exit 1
fi

typing_marker=$(grep -E "$marker_regex" "$vala" | tail -n 1)
typing_counts=$(printf '%s\n' "$typing_marker" | sed -n 's#.* result: \([0-9][0-9]*\)/\([0-9][0-9]*\) zvals left#\1 \2#p')
if [ -z "$typing_counts" ]; then
    echo "could not parse typing optimizer marker count: $typing_marker" >&2
    cat "$vala" >&2
    exit 1
fi
set -- $typing_counts
if [ "$1" -gt 0 ]; then
    expected_warning="WARNING: PERFORMANCE NOT OPTIMIZED THROUGH DYNAMIC ZVALS ($1/$2 zvals left)"
    if ! grep -Fq "$expected_warning" "$typing_stderr"; then
        echo "expected typing optimizer warning: $expected_warning" >&2
        cat "$typing_stderr" >&2
        exit 1
    fi
    if ! grep -q $'\033\[31m' "$typing_stderr" || ! grep -q $'\033\[0m' "$typing_stderr"; then
        echo "captured typing stderr must contain red ANSI escape codes" >&2
        cat "$typing_stderr" >&2
        exit 1
    fi
fi

if grep -q 'phpfunc_shell_exec' "$vala"; then
    library_marker=$(grep -E "$library_marker_regex" "$vala" | tail -n 1)
    counts=$(printf '%s\n' "$library_marker" | sed -n 's#.* result: \([0-9][0-9]*\)/\([0-9][0-9]*\) embed libphp\.so calls left.*#\1 \2#p')
    if [ -z "$counts" ]; then
        echo "could not parse library optimizer marker count: $library_marker" >&2
        cat "$vala" >&2
        exit 1
    fi
    set -- $counts
    if [ "$1" != "$2" ] || [ "$2" -lt 1 ]; then
        echo "expected shell_exec/phpfunc_shell_exec to leave a non-zero no-op library count, got: $library_marker" >&2
        cat "$vala" >&2
        exit 1
    fi
    expected_warning_prefix="WARNING: PERFORMANCE NOT OPTIMIZED, USING libphp.so ($1/$2 embed libphp.so calls left"
    if ! grep -Fq "$expected_warning_prefix" "$library_stderr"; then
        echo "expected library optimizer warning prefix: $expected_warning_prefix" >&2
        cat "$library_stderr" >&2
        exit 1
    fi
    if ! grep -Fq "shell_exec()" "$library_stderr" || ! grep -Fq "shell_exec()" "$vala"; then
        echo "expected library optimizer marker/warning to list original PHP call shell_exec()" >&2
        cat "$library_stderr" >&2
        cat "$vala" >&2
        exit 1
    fi
    if ! grep -q $'\033\[31m' "$library_stderr" || ! grep -q $'\033\[0m' "$library_stderr"; then
        echo "captured library stderr must contain red ANSI escape codes" >&2
        cat "$library_stderr" >&2
        exit 1
    fi
fi

printf 'ok - ValaIR optimizer markers are present in afteropt bundles and Vala output\n'
