#!/bin/sh
set -eu

: "${PRE15_DUT:?PRE15_DUT is required}"
: "${PRE15_ROOT:?PRE15_ROOT is required}"
: "${PRE15_CASE_TMP:?PRE15_CASE_TMP is required}"
: "${PRE15_RUN_DIR:?PRE15_RUN_DIR is required}"
: "${PRE15_LIB_DIR:?PRE15_LIB_DIR is required}"
. "$PRE15_LIB_DIR/runner.sh"

baseline=93d0c64e321f50cf68026c3f1c0c95293bf17302
case_script=$PRE15_DUT/tests/pre15/cases/B33-cache-policy.sh
fixture_dir=$PRE15_DUT/tests/pre15/fixtures
gate_dir=$PRE15_DUT/tests/pre15/gates
oracle=$fixture_dir/B33-cache-oracle.c
qemu_spec=$fixture_dir/B33-cache-state.json
qemu_generator=$fixture_dir/B33-cache-generate.py
qemu_runner=$fixture_dir/B33-qemu-run.sh
b32_probe=$fixture_dir/B32-cache-probe.c
kld_builder=$fixture_dir/B28-build-kld.sh
gate_input=$gate_dir/P15-038-input.json
gate_result=$PRE15_ROOT/planning/pre15/evidence/20260816T021736Z-G05-P15-038/result.json
gate_benefit=$PRE15_ROOT/planning/pre15/evidence/20260816T021736Z-G05-P15-038/benefit.json
gate_state=$PRE15_ROOT/planning/pre15/evidence/20260816T021736Z-G05-P15-038/state-model.json
gate_hashes=$PRE15_ROOT/planning/pre15/evidence/20260816T021736Z-G05-P15-038/SHA256SUMS
artifacts=$PRE15_RUN_DIR/artifacts

for tool in cc git python3 sha256sum timeout; do
	command -v "$tool" >/dev/null 2>&1 || \
		pre15_infra_blocked "missing B33 host tool: $tool"
done
for fixture in "$case_script" "$oracle" "$qemu_spec" "$qemu_generator" "$qemu_runner" \
    "$b32_probe" "$kld_builder" "$gate_input" "$gate_result" \
    "$gate_benefit" "$gate_state" "$gate_hashes"; do
	pre15_record_fixture "b33-$(basename "$fixture")" "$fixture"
done
for source in internal.h zdata.c; do
	pre15_record_fixture "b33-$source" "$PRE15_DUT/src/$source"
done
mkdir -p "$artifacts"

if test "${PRE15_QEMU_TARGET_ONLY:-0}" = 1; then
	pre15_target_reached
else
if ! python3 -B - "$PRE15_ROOT" "$PRE15_DUT" "$baseline" "$gate_input" \
    "$gate_result" "$gate_benefit" "$gate_state" \
    "$artifacts/B33-source-audit.json" <<'PY'
from __future__ import annotations

import json
from pathlib import Path
import re
import subprocess
import sys


root = Path(sys.argv[1])
dut = Path(sys.argv[2])
baseline = sys.argv[3]
implementation = "bc56f830918b76029871b60cca2e53992de70a2e"
current_owners = {
    "internal.h": "aa20623132b6821c6ad4651b263fc0ac0f7a14c8",
    "zdata.c": implementation,
}
gate_input = json.loads(Path(sys.argv[4]).read_text(encoding="ascii"))
gate_result = json.loads(Path(sys.argv[5]).read_text(encoding="ascii"))
gate_benefit = json.loads(Path(sys.argv[6]).read_text(encoding="ascii"))
gate_state = json.loads(Path(sys.argv[7]).read_text(encoding="ascii"))
report_path = Path(sys.argv[8])


def fail(message: str) -> None:
    raise SystemExit(message)


def committed(commit: str, relative: str) -> str:
    completed = subprocess.run(
        ["git", "-C", str(root), "show", f"{commit}:{relative}"],
        check=False,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True,
        timeout=30,
    )
    if completed.returncode != 0:
        fail(f"cannot read B33 source {commit}:{relative}: {completed.stderr.strip()}")
    return completed.stdout


def function(source: str, name: str) -> str:
    match = re.search(rf"\n(?:static\s+)?[^\n]+\n{name}\([^{{]+\n\{{", source)
    if match is None:
        fail(f"cannot locate function {name}")
    start = match.start() + 1
    brace = source.find("{", match.start())
    depth = 0
    for index in range(brace, len(source)):
        if source[index] == "{":
            depth += 1
        elif source[index] == "}":
            depth -= 1
            if depth == 0:
                return source[start : index + 1]
    fail(f"unterminated function {name}")


expected_changed = {
    "repo-pre-15/src/internal.h",
    "repo-pre-15/src/zdata.c",
    "repo-pre-15/tests/pre15/cases/B33-cache-policy.sh",
    "repo-pre-15/tests/pre15/fixtures/B33-cache-generate.py",
    "repo-pre-15/tests/pre15/fixtures/B33-cache-oracle.c",
    "repo-pre-15/tests/pre15/fixtures/B33-cache-state.json",
    "repo-pre-15/tests/pre15/fixtures/B33-qemu-run.sh",
}
changed = subprocess.run(
    [
        "git",
        "-C",
        str(root),
        "diff-tree",
        "--no-commit-id",
        "--name-only",
        "-r",
        implementation,
    ],
    check=True,
    stdout=subprocess.PIPE,
    text=True,
    timeout=30,
).stdout.splitlines()
if set(changed) != expected_changed or len(changed) != len(expected_changed):
    fail(f"B33 implementation write set mismatch: {changed!r}")

for name, commit in (("baseline", baseline), ("implementation", implementation)):
    if subprocess.check_output(
        ["git", "-C", str(root), "rev-parse", commit], text=True
    ).strip() != commit:
        fail(f"B33 {name} identity changed")

internal = (dut / "src/internal.h").read_text(encoding="utf-8")
zdata = (dut / "src/zdata.c").read_text(encoding="utf-8")
implemented_internal = committed(implementation, "repo-pre-15/src/internal.h")
implemented_zdata = committed(implementation, "repo-pre-15/src/zdata.c")
for name, source in (("internal.h", internal), ("zdata.c", zdata)):
    owner = current_owners[name]
    if source != committed(owner, f"repo-pre-15/src/{name}"):
        fail(f"current B33 source differs from accepted owner {owner}: {name}")

baseline_zdata = committed(baseline, "repo-pre-15/src/zdata.c")
for preserved in ("z_erofs_decode_length", "z_erofs_decode_extent"):
    if function(implemented_zdata, preserved) != function(baseline_zdata, preserved):
        fail(f"B25/B27/B28 read/decode path changed in B33: {preserved}")

do_read = function(implemented_zdata, "z_erofs_do_read")
baseline_do_read = function(baseline_zdata, "z_erofs_do_read")
bypass_delta = (
    "\t\t\t} else\n"
    "\t\t\t\tz_erofs_extent_cache_record_bypass(sbi, &map);"
)
if do_read.count(bypass_delta) != 1 or do_read.replace(bypass_delta, "\t\t\t}") != baseline_do_read:
    fail("B33 z_erofs_do_read differs beyond policy-rejection accounting")

required_b32 = (
    "cache->nid == vi->nid",
    "cache->decoded_size == decoded_size",
    "cache->map.m_pa == map->m_pa",
    "cache->map.m_la == map->m_la",
    "cache->map.m_plen == map->m_plen",
    "cache->map.m_llen == map->m_llen",
    "cache->map.m_deviceid == map->m_deviceid",
    "cache->map.m_algorithmformat == map->m_algorithmformat",
    "cache->map.m_flags == map->m_flags",
    "cache->state == EROFS_ZCACHE_INFLIGHT || cache->waiters != 0",
    "cv_wait(&cache->cv, &sbi->z_extent_cache_lock)",
    "cache->error = error",
    "cache->closing = true",
    "Z_EROFS_CACHE_BYPASS",
    "free(decoded, M_EROFS);",
)
missing = [token for token in required_b32 if token not in zdata]
if missing:
    fail(f"B32 key/inflight/failure/fallback token missing: {missing!r}")

policy = function(zdata, "z_erofs_extent_cache_eligible")
for named_codec in (
    "Z_EROFS_COMPRESSION_LZ4",
    "Z_EROFS_COMPRESSION_LZMA",
    "Z_EROFS_COMPRESSION_DEFLATE",
    "Z_EROFS_COMPRESSION_ZSTD",
):
    if named_codec in policy:
        fail(f"B33 admission still names a codec: {named_codec}")
for token in (
    "map->m_algorithmformat < Z_EROFS_COMPRESSION_MAX",
    "len <= cache->budget_bytes",
    "decode_work >= cache->minimum_decode_work",
    "z_erofs_cache_enabled != 0",
):
    if token not in policy:
        fail(f"codec-neutral work/size policy token is absent: {token}")
if "map->m_algorithmformat == Z_EROFS_COMPRESSION_LZMA" in zdata:
    fail("LZMA-only admission branch remains")
record_bypass = function(zdata, "z_erofs_extent_cache_record_bypass")
if "++cache->metrics[map->m_algorithmformat].bypasses" not in record_bypass or (
    "z_erofs_extent_cache_record_bypass(sbi, &map)" not in do_read
):
    fail("B33 policy rejection is absent from four-codec accounting")

budget = gate_input["budget"]
expected_macros = {
    "EROFS_ZCACHE_MOUNT_HARD_BUDGET": budget["per_mount_bytes"] // 1024,
    "EROFS_ZCACHE_GLOBAL_HARD_BUDGET": budget["global_bytes"] // 1024,
    "EROFS_ZCACHE_MIN_DECODE_WORK": budget["minimum_decode_work_bytes"] // 1024,
}
for name, kib in expected_macros.items():
    if f"#define {name} ({kib}UL * 1024)" not in zdata:
        fail(f"B33 hard policy differs from G05: {name}")
for token in (
    'TUNABLE_INT("vfs.erofs.decoded_cache.enabled"',
    'TUNABLE_ULONG("vfs.erofs.decoded_cache.mount_budget"',
    'TUNABLE_ULONG("vfs.erofs.decoded_cache.global_budget"',
    'TUNABLE_ULONG("vfs.erofs.decoded_cache.minimum_decode_work"',
    "MIN(z_erofs_cache_mount_budget,",
    "MIN(z_erofs_cache_global_budget,",
    "EVENTHANDLER_REGISTER(vm_lowmem",
    "EVENTHANDLER_DEREGISTER(vm_lowmem",
    "LIST_FOREACH(sbi, &z_erofs_cache_mounts, z_extent_cache_link)",
    "mtx_trylock(&sbi->z_extent_cache_lock)",
):
    if token not in zdata:
        fail(f"B33 budget/config/reclaim token is absent: {token}")

claim = function(zdata, "z_erofs_extent_cache_claim")
if claim.find("z_erofs_extent_cache_reserve(decoded_size)") > claim.find(
    "cache->state = EROFS_ZCACHE_INFLIGHT"
):
    fail("B33 does not reserve before inflight decode")
drop_position = claim.find("z_erofs_extent_cache_drop_locked(cache, true, false)")
empty_position = claim.find("cache->state = EROFS_ZCACHE_EMPTY", drop_position)
reserve_position = claim.find("z_erofs_extent_cache_reserve(decoded_size)")
if drop_position < 0 or not (drop_position < empty_position < reserve_position):
    fail("B33 replacement reservation failure can leave READY without data")
complete = function(zdata, "z_erofs_extent_cache_complete")
if complete.find("z_erofs_extent_cache_release(cache->charged_bytes)") > complete.find(
    "cache->state = EROFS_ZCACHE_FAILED"
):
    fail("B33 failed decode publishes before releasing reservation")

for field in (
    "hits",
    "misses",
    "bypasses",
    "evictions",
    "reclaims",
    "resident_bytes",
    "charged_bytes",
    "budget_bytes",
    "minimum_decode_work",
    "metrics[Z_EROFS_COMPRESSION_MAX]",
):
    if field not in internal:
        fail(f"B33 four-codec accounting field is absent: {field}")
for forbidden in ("shrinker", "workqueue", "work_struct", "wait_on_bit", "folio"):
    if forbidden in internal + zdata:
        fail(f"Linux-only cache primitive introduced: {forbidden}")

if gate_result.get("status") != "GO" or gate_result.get("b33") != "AUTHORIZED":
    fail("P15-038 G05 result is not GO")
if gate_state.get("status") != "PASS" or gate_state["budget"]["global_remaining"] != 0:
    fail("P15-038 state model is not closed")
if gate_benefit.get("codecs_meeting_threshold", 0) < 2 or any(
    len(summary["current_ns"]) != 5 or len(summary["candidate_ns"]) != 5
    for summary in gate_benefit.get("summaries", [])
):
    fail("P15-038 fixed five-sample benefit is incomplete")

report = {
    "baseline": baseline,
    "batch": "B33",
    "b32_contract_preserved": True,
    "codec_neutral": True,
    "current_owners": current_owners,
    "gate_codecs_meeting_threshold": gate_benefit["codecs_meeting_threshold"],
    "global_hard_budget": budget["global_bytes"],
    "implementation": implementation,
    "lock_order": ["global-list", "mount-cache", "global-budget"],
    "mount_hard_budget": budget["per_mount_bytes"],
    "no_cache_fallback": True,
    "reclaim": "FreeBSD-vm_lowmem",
    "write_set": sorted(changed),
}
report_path.write_text(json.dumps(report, indent=2, sort_keys=True) + "\n", encoding="ascii")
print(json.dumps(report, indent=2, sort_keys=True))
PY
then
	pre15_runner_fail 'B33 source, gate, write-set, or preservation audit failed'
fi

if ! (cd "$PRE15_ROOT/planning/pre15/evidence/20260816T021736Z-G05-P15-038" && \
    timeout -k 5 30 sha256sum -c SHA256SUMS) \
    >"$artifacts/gate-manifest.stdout" 2>"$artifacts/gate-manifest.stderr"; then
	pre15_runner_fail 'P15-038 gate evidence manifest failed'
fi
if ! cc -std=c11 -O2 -Wall -Wextra -Werror "$oracle" \
    -o "$PRE15_CASE_TMP/B33-cache-oracle" \
    >"$artifacts/oracle-build.stdout" 2>"$artifacts/oracle-build.stderr"; then
	pre15_runner_fail 'B33 cache budget oracle did not compile'
fi
if ! timeout -k 5 60 "$PRE15_CASE_TMP/B33-cache-oracle" \
    >"$artifacts/oracle.json" 2>"$artifacts/oracle.stderr"; then
	pre15_dut_fail 'B33 cache budget/accounting oracle failed'
fi
if ! python3 -B - "$artifacts/oracle.json" <<'PY'
import json
from pathlib import Path
import sys

result = json.loads(Path(sys.argv[1]).read_text(encoding="ascii"))
if result.get("status") != "PASS":
    raise SystemExit("B33 oracle status is not PASS")
if result.get("global_peak") != result.get("global_limit") or result.get("global_remaining") != 0:
    raise SystemExit("B33 oracle global budget did not close")
metrics = result.get("metrics", [])
if len(metrics) != 4 or [item.get("codec") for item in metrics] != list(range(4)):
    raise SystemExit("B33 four-codec metric set is incomplete")
for item in metrics:
    if item.get("hits", 0) < 1 or item.get("misses", 0) < 1 or item.get("evictions", 0) < 1:
        raise SystemExit(f"B33 codec metric is incomplete: {item!r}")
    if item.get("resident_bytes") != 0:
        raise SystemExit(f"B33 codec resident bytes leaked: {item!r}")
PY
then
	pre15_dut_fail 'B33 four-codec accounting result is incomplete'
fi

sha256sum "$artifacts/B33-source-audit.json" "$artifacts/oracle.json" \
    "$artifacts/gate-manifest.stdout" >"$artifacts/SHA256SUMS"
fi
pre15_target_reached

if test "${PRE15_MODE:-host}" != qemu; then
	printf '%s\n' \
		'B33-cache-budget host PASS' \
		'Four-codec admission/accounting, mount/global hard budgets, exhaustion fallback, reclaim, failure retry, disable, and eviction hash PASS' \
		'P15-038 host codec-cost gate replay manifest PASS; no guest vnode performance claimed' \
		'TC084/TC105/TC129 NOT_RUN (not necessary)' \
		'QEMU TC168, TC130, and full feature suite NOT_RUN in host mode'
	exit 0
fi

test "${PRE15_B32_SCENARIO:-}" = TC168-cache-inflight || \
	pre15_runner_fail 'B33 QEMU mode requires TC168-cache-inflight'
for tool in clang cmp diff file mkfs.erofs nm scp tar timeout; do
	command -v "$tool" >/dev/null 2>&1 || \
		pre15_infra_blocked "missing B33 QEMU tool: $tool"
done
: "${PRE15_QEMU_CONTROL_PATH:?QEMU control path is required}"
: "${PRE15_QEMU_SSH_KEY:?QEMU SSH key is required}"
: "${PRE15_QEMU_SSH_PORT:?QEMU SSH port is required}"
: "${PRE15_QEMU_SSH_USER:?QEMU SSH user is required}"

first=$PRE15_CASE_TMP/fixtures-first
second=$PRE15_CASE_TMP/fixtures-second
if ! (umask 022 && timeout -k 5 180 python3 -B "$qemu_generator" \
    --spec "$qemu_spec" --output "$first") \
    >"$artifacts/generate-first.json" 2>"$artifacts/generate-first.stderr" || \
    ! (umask 022 && timeout -k 5 180 python3 -B "$qemu_generator" \
    --spec "$qemu_spec" --output "$second") \
    >"$artifacts/generate-second.json" 2>"$artifacts/generate-second.stderr"; then
	pre15_runner_fail 'B33 fixture generation failed'
fi
if ! diff -qr "$first" "$second" >"$artifacts/fixture-repeat.diff"; then
	pre15_runner_fail 'B33 fixtures are not byte reproducible'
fi
cp "$first/fixture-index.json" "$artifacts/B33-fixture-index.json"

module=$PRE15_CASE_TMP/B33-erofs-zstdio0.ko
if ! timeout -k 10 600 /bin/sh "$kld_builder" "$PRE15_DUT" \
    "$PRE15_FREEBSD_SRC" "$module" "$PRE15_CASE_TMP/kld-work" 0 \
    >"$artifacts/kld-build.stdout" 2>"$artifacts/kld-build.stderr"; then
	pre15_dut_fail 'B33 cross-target zstdio0 KLD build failed'
fi
pre15_record_module "$module"
file "$module" >"$artifacts/kld-file.txt"
sha256sum "$module" >"$artifacts/kld-sha256.txt"
nm -u "$module" | LC_ALL=C sort >"$artifacts/kld-nm-u.txt"

fixture_archive=$PRE15_CASE_TMP/B33-fixtures.tar.gz
tar -C "$first" -czf "$fixture_archive" .

pre15_scp()
{
	timeout -k 5 "${PRE15_GUEST_COMMAND_TIMEOUT:-60}" scp -O -q \
		-o BatchMode=yes -o StrictHostKeyChecking=no \
		-o UserKnownHostsFile=/dev/null -o ConnectTimeout=5 \
		-o "ControlPath=$PRE15_QEMU_CONTROL_PATH" \
		-i "$PRE15_QEMU_SSH_KEY" -P "$PRE15_QEMU_SSH_PORT" \
		"$1" "$PRE15_QEMU_SSH_USER@127.0.0.1:$2"
}

pre15_guest_ssh_bounded()
{
	timeout -k 5 "${PRE15_GUEST_COMMAND_TIMEOUT:-60}" ssh -n -q \
		-o BatchMode=yes -o StrictHostKeyChecking=no \
		-o UserKnownHostsFile=/dev/null -o ConnectTimeout=5 \
		-o "ControlPath=$PRE15_QEMU_CONTROL_PATH" \
		-p "$PRE15_QEMU_SSH_PORT" \
		"$PRE15_QEMU_SSH_USER@127.0.0.1" "$@"
}

if ! pre15_scp "$fixture_archive" /root/B33-fixtures.tar.gz || \
    ! pre15_scp "$b32_probe" /root/B33-cache-probe.c || \
    ! pre15_scp "$module" /root/B33-erofs-zstdio0.ko; then
	pre15_infra_blocked 'could not transfer B33 module, probe, or fixtures'
fi
if ! pre15_guest_ssh_bounded \
    'rm -rf /root/B33-fixtures && mkdir /root/B33-fixtures && tar -xzf /root/B33-fixtures.tar.gz -C /root/B33-fixtures && cc -O2 -Wall -Wextra -Werror -pthread -o /root/B33-cache-probe /root/B33-cache-probe.c'; then
	pre15_infra_blocked 'could not prepare B33 guest fixtures/probe'
fi
if pre15_guest_ssh_bounded kldstat -q -m erofs >/dev/null 2>&1; then
	pre15_infra_blocked 'guest kernel already owns the erofs.1 interface'
fi
module_sha256=$(sha256sum "$module" | awk '{print $1}')
guest_module_sha256=$(pre15_guest_ssh_bounded sha256 -q /root/B33-erofs-zstdio0.ko) || \
	pre15_infra_blocked 'could not hash transferred B33 KLD'
printf 'host=%s guest=%s\n' "$module_sha256" "$guest_module_sha256" \
    >"$artifacts/guest-module-sha256.txt"
test "$guest_module_sha256" = "$module_sha256" || \
	pre15_runner_fail 'transferred B33 KLD hash differs from host module'
pre15_guest_ssh_bounded kldstat >"$artifacts/guest-kldstat-before-load.txt"
pre15_guest_ssh_bounded dmesg >"$artifacts/guest-dmesg-before-load.txt"
cache_tunable=vfs.erofs.decoded_cache.minimum_decode_work
cache_tunable_before=$(pre15_guest_ssh_bounded kenv -q "$cache_tunable" || true)
printf 'name=%s before=%s test-value=0\n' "$cache_tunable" \
    "${cache_tunable_before:-unset}" >"$artifacts/cache-tunable.txt"
if ! pre15_guest_ssh_bounded kenv "$cache_tunable=0" \
    >"$artifacts/cache-tunable-set.stdout" \
    2>"$artifacts/cache-tunable-set.stderr"; then
	pre15_infra_blocked 'could not force B33 decoded-cache admission'
fi
if ! pre15_guest_ssh_bounded kldload /root/B33-erofs-zstdio0.ko \
    >"$artifacts/kldload.stdout" 2>"$artifacts/kldload.stderr"; then
	if test -n "$cache_tunable_before"; then
		pre15_guest_ssh_bounded kenv "$cache_tunable=$cache_tunable_before" || true
	else
		pre15_guest_ssh_bounded kenv -u "$cache_tunable" || true
	fi
	if grep -q 'module already loaded or in kernel' \
	    "$artifacts/kldload.stderr"; then
		pre15_infra_blocked 'guest kernel already owns the erofs.1 interface'
	fi
	pre15_dut_fail 'B33 exact-source zstdio0 KLD failed to load'
fi
if test -n "$cache_tunable_before"; then
	pre15_guest_ssh_bounded kenv "$cache_tunable=$cache_tunable_before" \
    >"$artifacts/cache-tunable-restore.stdout" \
    2>"$artifacts/cache-tunable-restore.stderr" || \
		pre15_infra_blocked 'could not restore B33 cache tunable'
else
	pre15_guest_ssh_bounded kenv -u "$cache_tunable" \
    >"$artifacts/cache-tunable-restore.stdout" \
    2>"$artifacts/cache-tunable-restore.stderr" || \
		pre15_infra_blocked 'could not remove B33 cache tunable override'
fi
cache_tunable_after=$(pre15_guest_ssh_bounded kenv -q "$cache_tunable" || true)
printf 'after=%s\n' "${cache_tunable_after:-unset}" \
    >>"$artifacts/cache-tunable.txt"
if test "$cache_tunable_after" != "$cache_tunable_before"; then
	pre15_runner_fail 'B33 cache tunable was not restored exactly'
fi
if ! pre15_guest_ssh_bounded kldstat -q -m erofs; then
	pre15_dut_fail 'B33 kldload returned success without erofs.1 ownership'
fi
if ! pre15_guest_ssh_bounded kldstat -q -n B33-erofs-zstdio0.ko; then
	pre15_dut_fail 'B33 kldload returned success without exact KLD file ownership'
fi
pre15_guest_ssh_bounded kldstat >"$artifacts/guest-kldstat-after-load.txt"
pre15_guest_ssh_bounded dmesg >"$artifacts/guest-dmesg-before.txt"
diff -u "$artifacts/guest-dmesg-before-load.txt" \
    "$artifacts/guest-dmesg-before.txt" >"$artifacts/guest-dmesg-load.diff" || true
sed -n '/^+++ /d; /^+/s/^+//p' "$artifacts/guest-dmesg-load.diff" \
    >"$artifacts/guest-dmesg-load-added.txt"
if grep -Eqi 'panic:|lock order reversal|witness.*warning|use-after-free|fatal trap|pager fault|linker.*(error|undefined)|undefined symbol' \
    "$artifacts/guest-dmesg-load-added.txt"; then
	pre15_dut_fail 'B33 exact-source KLD load produced kernel or linker errors'
fi
pre15_own_guest_kld B33-erofs-zstdio0.ko 'B33 exact-source KLD'
pre15_guest_ssh_bounded kldstat >"$artifacts/guest-kldstat-before-trace.txt"
if ! pre15_guest_ssh_bounded command -v dtrace \
    >"$artifacts/guest-dtrace-command.txt" 2>"$artifacts/guest-dtrace-command.stderr"; then
	pre15_infra_blocked 'guest dtrace tool is unavailable for B33 call proof'
fi
set +e
pre15_guest_ssh_bounded kldload dtraceall \
    >"$artifacts/guest-dtrace-kldload.stdout" \
    2>"$artifacts/guest-dtrace-kldload.stderr"
dtrace_load_rc=$?
set -e
pre15_guest_ssh_bounded kldstat >"$artifacts/guest-kldstat-after-trace.txt"
awk 'NR == FNR { if (FNR > 1) seen[$5] = 1; next }
    FNR > 1 && !seen[$5] { print $1 "\t" $5 }' \
    "$artifacts/guest-kldstat-before-trace.txt" \
    "$artifacts/guest-kldstat-after-trace.txt" \
    >"$artifacts/guest-trace-klds-all.tsv"
awk '$2 == "dtraceall.ko"' "$artifacts/guest-trace-klds-all.tsv" \
    >"$artifacts/guest-trace-klds.tsv"
while IFS="$(printf '\t')" read -r trace_kld_id trace_kld_name; do
	test -n "$trace_kld_id" || continue
	pre15_own_guest_kld "$trace_kld_name" 'B33 FBT call-proof dependency'
done <"$artifacts/guest-trace-klds.tsv"
test "$dtrace_load_rc" -eq 0 || \
	pre15_infra_blocked 'guest dtraceall KLD failed to load for B33 call proof'
if ! pre15_guest_ssh_bounded \
    "dtrace -l -n 'fbt::z_erofs_extent_cache_init:entry' -n 'fbt::z_erofs_do_read:entry'" \
    >"$artifacts/guest-dtrace-probe-list.txt" \
    2>"$artifacts/guest-dtrace-probe-list.stderr"; then
	pre15_infra_blocked 'B33 cache init/read FBT probes are unavailable'
fi
grep -q 'z_erofs_extent_cache_init.*entry' \
    "$artifacts/guest-dtrace-probe-list.txt" || \
	pre15_runner_fail 'B33 cache init FBT probe was not listed exactly'
grep -q 'z_erofs_do_read.*entry' \
    "$artifacts/guest-dtrace-probe-list.txt" || \
	pre15_runner_fail 'B33 compressed-read FBT probe was not listed exactly'

b33_unown()
{
	kind=$1
	value=$2
	tmp=$PRE15_CASE_TMP/ownership.$$
	awk -F '	' -v kind="$kind" -v value="$value" \
	    '!($1 == kind && $2 == value)' "$PRE15_OWNERSHIP_FILE" >"$tmp"
	mv "$tmp" "$PRE15_OWNERSHIP_FILE"
}

b33_attach()
{
	image=$1
	label=$2
	B33_MD=$(pre15_guest_ssh_bounded mdconfig -a -t vnode \
	    -f "/root/B33-fixtures/images/$image") || \
		pre15_dut_fail "$label md attach failed"
	case "$B33_MD" in
	md[0-9]*) ;;
	*) pre15_runner_fail "unexpected B33 md unit: $B33_MD" ;;
	esac
	pre15_own_guest_md "$B33_MD" "$label md"
	B33_MOUNT=/mnt/pre15-b33-$label
	pre15_guest_ssh_bounded mkdir -p "$B33_MOUNT"
	if test "${B33_TRACE_MOUNT:-0}" = 1; then
		mount_trace=/tmp/pre15-b33-cache-init.trace
		pre15_guest_ssh_bounded \
		    "dtrace -q -o '$mount_trace' -n 'fbt::z_erofs_extent_cache_init:entry { @calls = count(); } END { printa(@calls); }' -c 'mount -t erofs -o ro /dev/$B33_MD $B33_MOUNT'" \
		    >"$artifacts/valid-mount.stdout" \
		    2>"$artifacts/valid-mount.stderr" || \
			pre15_dut_fail "$label traced mount failed"
		pre15_guest_ssh_bounded cat "$mount_trace" \
		    >"$artifacts/guest-cache-init-fbt.txt"
		if ! awk '$1 ~ /^[0-9]+$/ && $1 > 0 { found = 1 }
		    END { exit !found }' "$artifacts/guest-cache-init-fbt.txt"; then
			pre15_dut_fail 'B33 guest mount did not call decoded-cache init'
		fi
	else
		pre15_guest_ssh_bounded mount -t erofs -o ro "/dev/$B33_MD" "$B33_MOUNT" || \
			pre15_dut_fail "$label mount failed"
	fi
	pre15_own_guest_mount "$B33_MOUNT" "$label mount"
}

b33_detach()
{
	if pre15_guest_ssh_bounded mount | grep -F " on $B33_MOUNT " >/dev/null; then
		pre15_guest_ssh_bounded umount "$B33_MOUNT" || \
			pre15_dut_fail "$B33_MOUNT unmount failed"
	fi
	b33_unown guest-mount "$B33_MOUNT"
	pre15_guest_ssh_bounded mdconfig -d -u "$B33_MD" || \
		pre15_dut_fail "$B33_MD detach failed"
	b33_unown guest-md "$B33_MD"
}

reference=/root/B33-fixtures/source/payload.bin
B33_TRACE_MOUNT=1
b33_attach lz4-valid.erofs valid
unset B33_TRACE_MOUNT
trace_file=/tmp/pre15-b33-do-read.trace
if ! pre15_guest_ssh_bounded \
    "dtrace -q -o '$trace_file' -n 'fbt::z_erofs_do_read:entry { @calls = count(); } END { printa(@calls); }' -c '/root/B33-cache-probe concurrent $B33_MOUNT/payload.bin $reference 0 64 4 0 65536'" \
    >"$artifacts/valid-concurrent.stdout" \
    2>"$artifacts/valid-concurrent.stderr"; then
	pre15_dut_fail 'TC168 valid full-extent concurrent reads diverged'
fi
if ! grep -qx 'concurrent PASS workers=64 loops=4 assertions=256 errno=0 offset=0 length=65536' \
    "$artifacts/valid-concurrent.stdout"; then
	pre15_runner_fail 'TC168 valid assertion count was not exactly 256'
fi
pre15_guest_ssh_bounded cat "$trace_file" \
    >"$artifacts/guest-do-read-fbt.txt"
if ! awk '$1 ~ /^[0-9]+$/ && $1 > 0 { found = 1 }
    END { exit !found }' "$artifacts/guest-do-read-fbt.txt"; then
	pre15_dut_fail 'B33 guest reads did not call the target read implementation'
fi
b33_detach

b33_attach lz4-truncated.erofs truncated
if ! pre15_guest_ssh_bounded /root/B33-cache-probe concurrent \
    "$B33_MOUNT/payload.bin" "$reference" 97 1 1 0 65536 \
    >"$artifacts/failure-single.stdout" \
    2>"$artifacts/failure-single.stderr"; then
	pre15_dut_fail 'TC168 single corrupt read did not return EINTEGRITY'
fi
if ! grep -qx 'concurrent PASS workers=1 loops=1 assertions=1 errno=97 offset=0 length=65536' \
    "$artifacts/failure-single.stdout"; then
	pre15_runner_fail 'TC168 single corrupt assertion count was not 1'
fi
if ! pre15_guest_ssh_bounded /root/B33-cache-probe concurrent \
    "$B33_MOUNT/payload.bin" "$reference" 97 64 2 0 65536 \
    >"$artifacts/failure-concurrent.stdout" \
    2>"$artifacts/failure-concurrent.stderr"; then
	pre15_dut_fail 'TC168 failure waiters did not receive EINTEGRITY'
fi
if ! grep -qx 'concurrent PASS workers=64 loops=2 assertions=128 errno=97 offset=0 length=65536' \
    "$artifacts/failure-concurrent.stdout"; then
	pre15_runner_fail 'TC168 failure assertion count was not exactly 128'
fi
b33_detach

pre15_guest_ssh_bounded dmesg >"$artifacts/guest-dmesg-after.txt"
diff -u "$artifacts/guest-dmesg-before.txt" \
    "$artifacts/guest-dmesg-after.txt" >"$artifacts/guest-dmesg.diff" || true
sed -n '/^+++ /d; /^+/s/^+//p' "$artifacts/guest-dmesg.diff" \
    >"$artifacts/guest-dmesg-added.txt"
if grep -Eqi 'panic:|lock order reversal|witness.*warning|use-after-free|fatal trap|pager fault|linker.*(error|undefined)|undefined symbol' \
    "$artifacts/guest-dmesg-added.txt"; then
	pre15_dut_fail 'TC168 produced panic, WITNESS, or UAF evidence'
fi
printf '%s\n' \
		'TC168-cache-inflight B33 QEMU PASS' \
		'Exact KLD ownership, FBT-proven cache init/read calls, full-extent success/failure waiters, unmount drain, and cleanup exercised' \
	'TC130 and full feature suite NOT_RUN'
