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

build_root=$1
entry_src=$2
lib1_src=$3
lib2_src=$4

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"

generator_src="$(dirname "$build_root")/src/valacodegen/vala_code_generator.php"
if grep -Eq 'append(SourceRegisterFunction|DeferredHelper)|topLevelFunctionToVala|sourceMainFunctionName' "$generator_src"; then
    echo 'valacodegen must not construct source/register/deferred helper functions anymore' >&2
    grep -En 'append(SourceRegisterFunction|DeferredHelper)|topLevelFunctionToVala|sourceMainFunctionName' "$generator_src" >&2 || true
    exit 1
fi

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

entry_ast="$work/dynamic_include_entry.phpast"
lib1_ast="$work/dynamic_lib1.phpast"
lib2_ast="$work/dynamic_lib2.phpast"
entry_phpir="$work/dynamic_include_entry.phpir"
lib1_phpir="$work/dynamic_lib1.phpir"
lib2_phpir="$work/dynamic_lib2.phpir"
entry_valair="$work/dynamic_include_entry.valair"
entry_vala="$work/dynamic_include_entry.vala"

"$php2ast" "$entry_src" "$entry_ast"
"$php2ast" "$lib1_src" "$lib1_ast"
"$php2ast" "$lib2_src" "$lib2_ast"
"$phpast2phpir" "$entry_ast" "$entry_phpir" --external-phpast "$lib1_ast" --external-phpast "$lib2_ast"
"$phpast2phpir" "$lib1_ast" "$lib1_phpir" --external-phpast "$entry_ast" --external-phpast "$lib2_ast"
"$phpast2phpir" "$lib2_ast" "$lib2_phpir" --external-phpast "$entry_ast" --external-phpast "$lib1_ast"
"$phpir2valair" "$entry_phpir" "$entry_valair" \
    --external-phpir "$lib1_phpir" \
    --external-phpir "$lib2_phpir" \
    --include-function lib1.php phpef_file_lib1_php \
    --source-function-prefix lib1.php lib1_php \
    --include-function lib2.php phpef_file_lib2_php \
    --source-function-prefix lib2.php lib2_php \
    --function-prefix dynamic_include_entry_php
"$valair_optimize" "$entry_valair" "$entry_valair.afteropt.typing-zval2static"
"$valair2vala" "$entry_valair.afteropt.typing-zval2static" "$entry_vala" --activation-function phpef_file_dynamic_include_entry_php

for needle in \
    'PhpefRuntimeCore.argv(Zval.from_int(1))' \
    'string __phpefc_include_path =' \
    'if (__phpefc_include_path == "lib1.php" || __phpefc_include_path.has_suffix("/lib1.php"))' \
    'phpef_file_lib1_php__register_functions();' \
    'phpef_file_lib1_php();' \
    'if (__phpefc_include_path == "lib2.php" || __phpefc_include_path.has_suffix("/lib2.php"))' \
    'phpef_file_lib2_php__register_functions();' \
    'phpef_file_lib2_php();' \
    'PhpefRuntimeCore.register_stacktrace_frame("phpef_file_dynamic_include_entry_php", "{main}");' \
    'PhpefRuntimeCore.register_stacktrace_frame("__phpefc_dynamic_include_' \
    'Failed opening required'; do
    if ! grep -Fq "$needle" "$entry_vala"; then
        echo "dynamic include Vala is missing: $needle" >&2
        cat "$entry_vala" >&2
        exit 1
    fi
done

if awk '
    /PHPEFC-C-SOURCE-LINES-BEGIN/ { exit found ? 0 : 1 }
    /__phpefc_include_path/ && /\/home\/peters\// { found=1 }
    END { exit found ? 0 : 1 }
' "$entry_vala"; then
    echo 'dynamic include dispatcher must not contain host-specific /home/peters/ match strings' >&2
    cat "$entry_vala" >&2
    exit 1
fi

if grep -Fq '__registered' "$entry_vala" || grep -Fq '__call' "$entry_vala"; then
    echo 'dynamic include unexpectedly reintroduced old wrapper registration model' >&2
    cat "$entry_vala" >&2
    exit 1
fi

if ! awk '
    /__phpefc_dynamic_include_[0-9]+_[0-9]+\(Zval\.from_string\("lib"\)/ { call_line=NR }
    /string __phpefc_include_path =/ { dispatch_line=NR }
    /public static void phpef_file_dynamic_include_entry_php__register_functions\(\)/ { register_line=NR }
    END { exit !(call_line > 0 && dispatch_line > call_line && register_line > dispatch_line) }
' "$entry_vala"; then
    echo 'dynamic include dispatcher/register_functions must be deferred after PHP-near activation code' >&2
    cat "$entry_vala" >&2
    exit 1
fi

if ! awk '
    /public static void phpef_file_dynamic_include_entry_php\(\)/ { in_activation=1; next }
    in_activation && /^}/ { in_activation=0 }
    in_activation && /string __phpefc_include_path =/ { found=1 }
    END { exit found ? 1 : 0 }
' "$entry_vala"; then
    echo 'dynamic include dispatcher leaked into PHP-near activation function' >&2
    cat "$entry_vala" >&2
    exit 1
fi

printf 'ok 1 - dynamic include lowers to argv/path expression with runtime source-set dispatch and registry activation\n'
