#!/usr/bin/env bash
# Reproduce, cold, the measurement behind "servo/unicode-bidi ran one third of its
# conformance suite". Needs: git, cargo, gcc, python3, curl. Nothing else.
#
#   bash reproduce.sh
#
# What it establishes, in order:
#   1. From BidiTest.txt alone, with no Rust involved: the file specifies 770241
#      (data line, paragraph direction) pairs, and upstream's filter selects 256747.
#   2. In the library, with upstream's filter: 256747 executed, all auto-LTR.
#   3. With the filter fixed: 770241 executed, 770241 passed.
#   4. The positive control: swap LTR and RTL and the newly enabled rows go red.
#      Without this step, step 3's zero failures would be worthless.
#   5. The one-character patch applied to the real harness, full suite green.
#   6. The same expression parsed by C and by Rust, which disagree on the grouping
#      and agree on all 21 answers.
set -euo pipefail
HERE=$(cd "$(dirname "$0")" && pwd)
WORK=${WORK:-$(mktemp -d)}
PIN=54190b8a8032deaddaacc484b13791c481acdd7a
echo "== working in $WORK"

git clone --quiet https://github.com/servo/unicode-bidi "$WORK/ub"
cd "$WORK/ub"
echo "== upstream HEAD is $(git log -1 --format='%h %cI')"
git checkout --quiet "$PIN"
echo "== pinned to  $(git log -1 --format='%h %cI %s')"
echo "== shipped conformance data: $(head -1 tests/data/BidiTest.txt | tr -d '#') / $(head -1 tests/data/BidiCharacterTest.txt | tr -d '#')"
echo "== crate declares UNICODE_VERSION $(grep -o '([0-9]*, [0-9]*, [0-9]*)' src/char_data/tables.rs | head -1)"

echo
echo "== 1. the data file, counted without running any Rust"
python3 - <<'PY'
from collections import Counter
h=Counter(); n=0; spec=[0,0,0]; sel=[0,0,0]
for line in open('tests/data/BidiTest.txt', encoding='utf-8'):
    line=line.strip()
    if not line or line[0] in '#@': continue
    b=int(line.split(';')[1].strip()); n+=1; h[b]+=1
    for bit in range(3):
        if b & (1<<bit): spec[bit]+=1
        # upstream's expression, as Rust parses it
        if (b & (1<<bit)) == 1: sel[bit]+=1
print(f"   data lines            : {n}")
print(f"   specified auto/LTR/RTL: {spec[0]} / {spec[1]} / {spec[2]}   total {sum(spec)}")
print(f"   upstream filter selects: {sel[0]} / {sel[1]} / {sel[2]}   total {sum(sel)}")
print( "   bitset histogram      : " + ", ".join(f"{k}:{h[k]}" for k in sorted(h)))
print( "   (note: bitsets 1 and 6 never occur; 7 occurs "
      f"{h[7]} times, which is the number that survives step 4)")
PY

cp "$HERE/measure/instrumented.rs" tests/instrumented.rs

echo
echo "== 2. in the library, with UPSTREAM's filter"
BIDI_FILTER_MODE=buggy cargo test --release --quiet --test instrumented -- --nocapture 2>/dev/null \
  | sed -n '/^direction/,/^TOTAL/p' | sed 's/^/   /'

echo
echo "== 3. with the filter FIXED (!= 0)"
BIDI_FILTER_MODE=fixed cargo test --release --quiet --test instrumented -- --nocapture 2>/dev/null \
  | sed -n '/^direction/,/^TOTAL/p' | sed 's/^/   /'

echo
echo "== 4. POSITIVE CONTROL: fixed filter, LTR and RTL swapped."
echo "      auto-LTR must stay green and the two new columns must go red."
BIDI_SWAP_DIRECTIONS=1 BIDI_FILTER_MODE=fixed cargo test --release --quiet --test instrumented -- --nocapture 2>/dev/null \
  | sed -n '/^direction/,/^TOTAL/p' | sed 's/^/   /'

rm tests/instrumented.rs

echo
echo "== 5. the real suite, before and after the one-character patch"
echo "   before:"
cargo test --release --quiet 2>&1 | grep -E "^test result" | sed 's/^/     /'
git apply --stat "$HERE/0001-conformance-all-three-directions.patch" | sed 's/^/   /'
git apply "$HERE/0001-conformance-all-three-directions.patch"
echo "   after:"
cargo test --release --quiet 2>&1 | grep -E "^test result" | sed 's/^/     /'

echo
echo "== 6. and against Unicode 17.0.0's own data, with the patch in place"
curl -sS -o tests/data/BidiTest.txt https://www.unicode.org/Public/17.0.0/ucd/BidiTest.txt
curl -sS -o tests/data/BidiCharacterTest.txt https://www.unicode.org/Public/17.0.0/ucd/BidiCharacterTest.txt
echo "   now testing against: $(head -1 tests/data/BidiTest.txt | tr -d '#') / $(head -1 tests/data/BidiCharacterTest.txt | tr -d '#')"
cargo test --release --quiet --test conformance_tests 2>&1 | grep -E "^test result" | sed 's/^/     /'
git checkout --quiet -- tests/data

echo
echo "== 7. the expression itself, in both languages"
gcc -w -o "$WORK/prec_c" "$HERE/measure/prec.c"
echo "   C  parses  bitset & 1u << bit == 1  as  bitset & ((1u << bit) == 1)"
echo "      rows where that differs from the intent: $("$WORK/prec_c" | grep -c differs) of 21"
rustc -O -o "$WORK/prec_rs" "$HERE/measure/prec.rs" 2>/dev/null
echo "   Rust parses it as  (bitset & (1u8 << bit)) == 1   [asserted in prec.rs]"
"$WORK/prec_rs" | tail -1 | sed 's/^/      /'

echo
echo "== done. working tree left in $WORK"
