#!/usr/bin/env bash
# v1.6.5 AC8 成对判据脚本 —— 【同一法】用于【修复前】/【修复后】二面
#
# 用法: ac8_paste_pair.sh <binary> <label> <outdir>
#   例: ac8_paste_pair.sh /home/ke/.local/bin/xwcode prefix /data1/km/tmp/ac8-prefix
#
# ★ 成对判据要件(承路标 AC8 ∧ ar 明订): 同载荷(250 B / 5 行) ∧ 同默认配置 ∧ 同 Ctrl-C 二态
# ★ 脚本自证: 对【修复前】二进制须复现 1/5(否则「修复后 5/5」不可采信 —— 无法排除脚本恒报成功)
# ★ 环境隔离: tmux -L 独立 socket ∧ XW_COMM_AGENT=memprobe-iso(非注册 ⇒ 结构性不消费真实队列)
set -uo pipefail

BIN="${1:?binary}"; LABEL="${2:?label}"; OUT="${3:?outdir}"
# v1.6.7 AC11(承 1d 阻塞 E4/ac8 零覆盖): 消【硬编码路径】—— 原 `PAYLOAD=/data1/km/tmp/ac8.txt`
#   系本机绝对路径(他机/CI 不可用 ∧ 与 OUT 面不一致 ⇒ 侧效污染)。现改由 OUT 派生。
PAYLOAD="$OUT/ac8_payload.txt"
SOCK="ac8pair-$$"
mkdir -p "$OUT"

# ── 载荷(250 B / 5 行, 与修复前读数【逐字同】)────────────────────────────
printf '%s\n' \
 'AC8PF-L1-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' \
 'AC8PF-L2-BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' \
 'AC8PF-L3-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC' \
 'AC8PF-L4-DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD' \
 'AC8PF-L5-EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' > "$PAYLOAD"

cleanup() { tmux -L "$SOCK" kill-server 2>/dev/null; }
trap cleanup EXIT

# ── ① 交互面: ★★ 二法并跑(粘贴法须【随应用声明而变】—— 见下)────────────────
#  ★ 忠实性: 真实终端在应用发 \e[?2004h【之后】才套 \e[200~…\e[201~ 包裹。
#    故【同一粘贴法用于二面】为【失真】—— 须由 ③ 发出面决定哪一法为忠实法。
rm -rf "$OUT/ws" && mkdir -p "$OUT/ws"
tmux -L "$SOCK" new-session -d -s p -x 140 -y 40 \
  "cd $OUT/ws && env XW_COMM_AGENT=memprobe-iso XW_COMM_MACHINE=ke $BIN; exec bash"
sleep 14
tmux -L "$SOCK" capture-pane -t p -p > "$OUT/frame_before.txt" 2>/dev/null
tmux -L "$SOCK" load-buffer "$PAYLOAD"

# 法 A: 裸贴(= 应用【未】声明时, 真实终端之行为)
tmux -L "$SOCK" paste-buffer -t p
sleep 8
tmux -L "$SOCK" capture-pane -t p -p -S -3000 > "$OUT/frame_raw.txt" 2>/dev/null
SUBMIT_RAW=$(grep -c '^> AC8PF' "$OUT/frame_raw.txt" 2>/dev/null); SUBMIT_RAW=${SUBMIT_RAW:-0}
tmux -L "$SOCK" kill-server 2>/dev/null

# 法 B: 标记贴(= 应用【已】声明时, 真实终端之行为)
rm -rf "$OUT/ws2" && mkdir -p "$OUT/ws2"
tmux -L "$SOCK" new-session -d -s p2 -x 140 -y 40 \
  "cd $OUT/ws2 && env XW_COMM_AGENT=memprobe-iso XW_COMM_MACHINE=ke $BIN; exec bash"
sleep 14
tmux -L "$SOCK" load-buffer "$PAYLOAD"
tmux -L "$SOCK" paste-buffer -p -t p2
sleep 8
tmux -L "$SOCK" capture-pane -t p2 -p -S -3000 > "$OUT/frame_brk.txt" 2>/dev/null
SUBMIT_BRK=$(grep -c '^> AC8PF' "$OUT/frame_brk.txt" 2>/dev/null); SUBMIT_BRK=${SUBMIT_BRK:-0}
KEPT_BRK=$(grep -o 'AC8PF-L[1-5]' "$OUT/frame_brk.txt" 2>/dev/null | sort -u | wc -l); KEPT_BRK=${KEPT_BRK:-0}
tmux -L "$SOCK" kill-server 2>/dev/null
SUBMITTED=$SUBMIT_RAW   # 兼容旧判据字段

# ── ② Ctrl-C 二态(★ 须分列; 须自有活会话 —— ① 已 kill server)─────────────
rm -rf "$OUT/ws3" && mkdir -p "$OUT/ws3"
tmux -L "$SOCK" new-session -d -s p3 -x 140 -y 40 \
  "cd $OUT/ws3 && env XW_COMM_AGENT=memprobe-iso XW_COMM_MACHINE=ke $BIN; exec bash"
sleep 14
tmux -L "$SOCK" load-buffer "$PAYLOAD"; tmux -L "$SOCK" paste-buffer -t p3; sleep 4
tmux -L "$SOCK" send-keys -t p3 C-c; sleep 5
tmux -L "$SOCK" capture-pane -t p3 -p -S -200 > "$OUT/ctrlc_busy.txt" 2>/dev/null
tmux -L "$SOCK" send-keys -t p3 C-c; sleep 4
tmux -L "$SOCK" capture-pane -t p3 -p -S -200 > "$OUT/ctrlc_idle.txt" 2>/dev/null
tmux -L "$SOCK" send-keys -t p3 'echo SHELL_OK_$(date +%s)' Enter; sleep 2
tmux -L "$SOCK" capture-pane -t p3 -p -S -200 > "$OUT/shell_probe.txt" 2>/dev/null
tmux -L "$SOCK" kill-server 2>/dev/null

# ── ③ 发出面: 原始字节流(★ 合法判据面; 存在面无判别力 —— 承裁定 31)──────
RAW="$OUT/raw.bin"; rm -f "$RAW"
rm -rf "$OUT/rawws" && mkdir -p "$OUT/rawws"
tmux -L "$SOCK" new-session -d -s r -x 140 -y 40 \
  "cd $OUT/rawws && env XW_COMM_AGENT=memprobe-iso XW_COMM_MACHINE=ke script -q -c $BIN $RAW; exec bash"
sleep 14
tmux -L "$SOCK" load-buffer "$PAYLOAD"; tmux -L "$SOCK" paste-buffer -t r; sleep 5
tmux -L "$SOCK" send-keys -t r C-c; sleep 4
tmux -L "$SOCK" send-keys -t r C-c; sleep 4
tmux -L "$SOCK" send-keys -t r C-c; sleep 4
tmux -L "$SOCK" kill-server 2>/dev/null
# ★ 取值面先证完整: 须【尾行现 Script done】(尺寸稳定不足 —— 块缓冲可使未完之档看似稳定)
RAW_OK=0
for _ in $(seq 1 20); do
  grep -aq 'Script done' "$RAW" 2>/dev/null && { RAW_OK=1; break; }
  sleep 1
done
RAW_BYTES=$(wc -c < "$RAW" 2>/dev/null); RAW_BYTES=${RAW_BYTES:-0}
RAW_COMPLETE=$RAW_OK

# ★ 零命中表示须钉死: `grep -c` 零命中 ⇒ 输出 "0" ∧ 退出码 1 ⇒ 禁 `|| echo 0`(会追加第二个 0)
emit() { local n; n=$(grep -ac -- "$1" "$RAW" 2>/dev/null); echo "${n:-0}"; }
EN2004=$(emit $'\033\[?2004h'); DIS2004=$(emit $'\033\[?2004l'); ANY2004=$(emit '2004')
C25L=$(emit $'\033\[?25l'); C25H=$(emit $'\033\[?25h'); DECR=$(emit $'\033\[r')

# ── ④ 判据输出(★ 逐项附谓词)────────────────────────────────────────────
{
echo "=== AC8 成对判据 · label=$LABEL ==="
echo "binary      : $BIN"
# ★ v1.6.7 裁决 50(立条(二十一)/(二十二)): 凡取值经管道者须核【工具面】——
#   `cut -c1-N` 于本机【按字节】切(实测: `printf '其者' | cut -c1-2` ⇒ `e5 85` = 非法 UTF-8);
#   字符安全形 = `LC_ALL=C.UTF-8 awk '{print substr($0,1,N)}'`。本处【已核其面】:
#   输入 = `sha256sum` 之输出 = 【纯 ASCII 十六进制】⇒ 字节 ≡ 字符 ⇒ 字节切无虞(非默认, 系核后之判)。
echo "binary sha  : $(sha256sum "$(readlink -f "$BIN")" 2>/dev/null | cut -c1-32)"
echo "version     : $("$BIN" --version 2>&1 | head -1)"
echo "payload     : $(wc -c < "$PAYLOAD") B / $(wc -l < "$PAYLOAD") 行"
echo
echo "--- ① 交互面(★ 二法并跑; 谓词: grep -c '^> AC8PF')---"
echo "  法A 裸贴   (应用【未】声明 ⇒ 真实终端行为): 提交 $SUBMIT_RAW/5"
echo "  法B 标记贴 (应用【已】声明 ⇒ 真实终端行为): 提交 $SUBMIT_BRK/5 ∧ 输入框留 AC8PF 行 $KEPT_BRK"
echo "  ★ 忠实法 = 由 ③ 发出面决定: \\e[?2004h≥1 ⇒ 取【法B】; =0 ⇒ 取【法A】"
echo
echo "--- ② Ctrl-C 二态(谓词: 语义行 grep, 非状态栏)---"
echo "  [处理中] $(grep -o '请求已取消\|cancelled by user' "$OUT/ctrlc_busy.txt" 2>/dev/null | tail -1 || echo '—')   ⇒ 应为【取消请求, 非退出】"
echo "  [空态]   $(grep -o 'restored to stderr\|end ───' "$OUT/ctrlc_idle.txt" 2>/dev/null | tail -1 || echo '—')   ⇒ 应为【退出】"
echo "  [shell]  $(grep -o 'SHELL_OK_[0-9]\+' "$OUT/shell_probe.txt" 2>/dev/null | tail -1 || echo '★ 未见回显')   ⇒ 应见回显(终端已还原)"
echo
echo "--- ③ 发出面(谓词: grep -ac 原始流)---"
echo "  取值面    : raw=$RAW_BYTES B ∧ Script done=$RAW_COMPLETE $([ "${RAW_COMPLETE:-0}" -ge 1 ] && echo '(完整 ✓)' || echo '(★ 未完 ⇒ 零命中不可采信)')"
echo "  \\e[?2004h : $EN2004   $([ "${EN2004:-0}" -ge 1 ] && echo '⇒ ★ 已启用 bracketed paste' || echo '⇒ 未启用')"
echo "  \\e[?2004l : $DIS2004"
echo "  '2004' 任意: $ANY2004"
echo "  阳性对照  : \\e[?25l=$C25L  \\e[?25h=$C25H  \\e[r=$DECR  (证 grep 法有效)"
} | tee "$OUT/summary.txt"

echo
echo "★★ 判据(忠实法):"
echo "   修复前 ⇒ ③ \\e[?2004h=0 ⇒ 取【法A】⇒ 期望 提交=1/5(丢失)"
echo "   修复后 ⇒ ③ \\e[?2004h≥1 ⇒ 取【法B】⇒ 期望 提交=0/5 ∧ 输入框留 5 行(完整)"
echo "★ 脚本自证: 二面【皆】须在【各自忠实法】下与上述相符"

# ── ⑤ 判据断言 ∧ 出口码(v1.6.7 AC11 · 承 1d 阻塞 E4)─────────────────────
# 据: 本件原【零 fail ∧ 零 exit】⇒ 末命令为 echo ⇒ 恒 rc=0 ⇒ 永不可能 FAIL(零覆盖)。
#   本块使【判据不成立即 rc≠0】, 且【删其实现块(tmux 实跑段)须变红】——
#   实现块一删, SUBMIT_*/KEPT_* 皆缺 ⇒ 下方断言必红(金标准: 假集成测试模式)。
FAIL=0
bad() { echo "FAIL(ac8): $*" >&2; FAIL=1; }

# ① 取值面完整性前置: 原始流未完 ⇒ 零命中不可采信(本件自载之律)
[[ "${RAW_COMPLETE:-0}" -ge 1 ]] || bad "原始流未完(未见 'Script done')⇒ 零命中不可采信, 判据不成立"

# ② 阳性对照: 控制序列 grep 法须有效(否则零命中可能是 grep 失灵而非行为正确)
if [[ "${C25L:-0}" -lt 1 && "${C25H:-0}" -lt 1 && "${DECR:-0}" -lt 1 ]]; then
    bad "阳性对照失效: 控制序列(\\e[?25l / \\e[?25h / \\e[r)于原始流零命中 ⇒ grep 法不承证力"
fi

# ③ 忠实法判定 + 二态期望(忠实法由 ③ 发出面决定 —— 承本件头注)
if [[ "${EN2004:-0}" -ge 1 ]]; then
    [[ "${SUBMIT_BRK:-0}" -eq 0 ]] || bad "修复后面(\\e[?2004h≥1 ⇒ 忠实法=法B): 期望 提交=0/5, 实得 ${SUBMIT_BRK}/5"
    [[ "${KEPT_BRK:-0}" -eq 5 ]] || bad "修复后面(忠实法=法B): 期望 输入框留 5 行, 实得 ${KEPT_BRK}"
else
    [[ "${SUBMIT_RAW:-0}" -eq 1 ]] || bad "修复前面(\\e[?2004h=0 ⇒ 忠实法=法A): 期望 提交=1/5, 实得 ${SUBMIT_RAW}/5"
fi

# ④ Ctrl-C 二态 + 终端还原(语义行 grep, 非状态栏)
grep -qE '请求已取消|cancelled by user' "$OUT/ctrlc_busy.txt" 2>/dev/null || bad "[处理中] Ctrl-C 期望【取消请求】, 未见"
grep -qE 'restored to stderr|end ───' "$OUT/ctrlc_idle.txt" 2>/dev/null || bad "[空态] Ctrl-C 期望【退出】, 未见"
grep -qE 'SHELL_OK_[0-9]+' "$OUT/shell_probe.txt" 2>/dev/null || bad "[shell] 终端还原探针未见回显"

if [[ "$FAIL" -eq 0 ]]; then
    echo "ac8 成对判据【成立】✓(label=$LABEL)"
else
    echo "ac8 成对判据【FAIL】(label=$LABEL)—— 见上方 FAIL(ac8) 行" >&2
fi
exit "$FAIL"