#!/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"
c_add_source_lines="$cli_dir/phpefc-c-add-source-lines"

for tool in "$php2ast" "$phpast2phpir" "$phpir2valair" "$valair2vala" "$c_add_source_lines"; 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/nested_throw.phpast"
phpir="$work/nested_throw.phpir"
valair="$work/nested_throw.valair"
vala="$work/nested_throw.vala"
fake_c="$work/nested_throw.c"
mapped_c="$work/nested_throw.mapped.c"
debug_bundle="$work/nested_throw.debug.json"

"$php2ast" "$src" "$phpast" >/dev/null
"$phpast2phpir" "$phpast" "$phpir" >/dev/null
"$phpir2valair" "$phpir" "$valair" >/dev/null
"$valair2vala" "$valair" "$vala" >/dev/null

throw_vala_line=$(python3 - "$src" "$vala" <<'PY'
import json, re, sys
from pathlib import Path
src, vala = sys.argv[1:]
text = Path(vala).read_text()
match = re.search(r'PHPEFC-C-SOURCE-LINES-BEGIN\n(.*?)\nPHPEFC-C-SOURCE-LINES-END', text, re.S)
if not match:
    raise SystemExit('source-map comment missing')
source_map = json.loads(match.group(1))
for mapping in source_map.get('mappings') or []:
    if mapping.get('phpSourceFile') == src and mapping.get('phpLine') == 7 and mapping.get('kind') == 'CallStatement':
        line = int(mapping['valaLine'])
        vala_lines = text.splitlines()
        if 'throw_exception' not in vala_lines[line - 1]:
            raise SystemExit('line 7 mapping does not point to throw_exception: ' + vala_lines[line - 1])
        print(line)
        break
else:
    raise SystemExit('missing throw runtime-call mapping for PHP line 7')
PY
)

cat > "$fake_c" <<C
#line $throw_vala_line "$(basename "$vala")"
void synthetic_nested_throw_line(void) {}
C

"$c_add_source_lines" "$fake_c" "$mapped_c" "$vala" "$debug_bundle" >/dev/null
expected="#line 7 \"$src\""
if ! grep -Fq "$expected" "$mapped_c"; then
    echo "expected mapped C to contain: $expected" >&2
    cat "$mapped_c" >&2
    exit 1
fi

printf 'ok 1 - nested foreach/if throw maps to PHP throw source line\n'
