#!/usr/bin/env bash
# Quick POG422 hat driver check — run on pos 1–4 after install_pi.sh + USB replug/reboot.
set -euo pipefail

KVER="$(uname -r)"
MOD="xr_usb_serial_common"
KO_EXTRA="/lib/modules/${KVER}/extra/${MOD}.ko"
KO_UPDATES="/lib/modules/${KVER}/updates/${MOD}.ko"
MIN_DRIVER="1Q-pog422-wide-preciseflags-only"
PREFERRED_DRIVER="2.2.1.1"
ACCEPT_DRIVERS=("2.2.1.1" "2.2.1.0" "2.1.0.0" "1W-pog422-tx-fifo-errno-ch" "1V-pog422-tx-fifo-dma-buf" "1U-pog422-tx-fifo-uart-block" "1T-pog422-tx-fifo-get-reg-fix" "1S-pog422-inject-tx-fifo-diag" "1R-pog422-preciseflags-ioctl-fix" "1Q-pog422-wide-preciseflags-only")
RS485_STRING_MARKERS=("2.2.1.1" "2.2.1.0" "EG 2.2" "2.1.0.0" "EG 2.1" "1W-pog422-tx-fifo-errno-ch" "POG422 1W" "1V-pog422-tx-fifo-dma-buf" "POG422 1V" "1U-pog422-tx-fifo-uart-block" "POG422 1U" "1T-pog422-tx-fifo-get-reg-fix" "POG422 1T" "1S-pog422-inject-tx-fifo-diag" "POG422 1S" "1R-pog422-preciseflags-ioctl-fix" "POG422 1R" "1Q-pog422-wide-preciseflags-only" "POG422 1Q" "1P-pog422-inject-wide-teardown-wait" "POG422 1P" "1O-pog422-inject-manual-de-hold" "POG422 1O" "1N-pog422-manual-gpio7-inject" "POG422 1N" "manual GPIO7" "1N mixed" "1M-pog422-wide-off-no-disable" "1L-pog422-inject-tx-wire-drain" "1K-pog422-inject-tx-drain" "1J-pog422-wide-inject-tx" "1I-pog422-dttty-rx-ring" "1H-pog422-rx-extra-byte-fix" "1G-pog422-rs485-mark-space-hold" "1F-pog422-rs485-auto" "GPIO7 RS485 auto" "POG422 RS485 auto")

ko_built_version() {
  modinfo "$1" 2>/dev/null | awk -F':[ \t]*' '/^version:/ { print $2; exit }'
}

modinfo_resolved_ko() {
  modinfo "${MOD}" 2>/dev/null | awk -F':[ \t]*' '/^filename:/ { print $2; exit }'
}

echo "=== POG422 driver verify ==="
echo "kernel: ${KVER}"
echo
echo "IMPORTANT:"
echo "  modinfo           = on-disk .ko (what would load NEXT)"
echo "  /sys/module/…/version = what is RUNNING NOW (inject uses this)"
echo

resolved="$(modinfo_resolved_ko)"
if [[ -z "${resolved}" ]]; then
  echo "FAIL: modinfo ${MOD} — module not installed" >&2
  exit 1
fi

echo "--- installed (modinfo / on-disk) ---"
echo "modinfo ${MOD} → ${resolved}"
resolved_ver="$(ko_built_version "${resolved}")"
modinfo "${MOD}" | grep -E '^(filename|version|description):' || true
echo "installed version: ${resolved_ver:-?}"

driver_version_ok() {
  local v="$1"
  local a
  for a in "${ACCEPT_DRIVERS[@]}"; do
    [[ "${v}" == "${a}" ]] && return 0
  done
  return 1
}

if ! driver_version_ok "${resolved_ver:-}"; then
  echo "FAIL: modprobe would load ${resolved_ver:-unknown}, want ${MIN_DRIVER} or ${PREFERRED_DRIVER}" >&2
  echo "  install_pi.sh puts the fork in updates/; extra/ alone is NOT enough." >&2
  echo "  Stale shadow copy?" >&2
  find "/lib/modules/${KVER}" -name "${MOD}.ko*" 2>/dev/null || true
  exit 1
fi

if [[ "${resolved_ver}" == "${MIN_DRIVER}" ]]; then
  echo "NOTE: ${MIN_DRIVER} on disk — uartd 1.0.52+ works around SET_PRECISE_FLAGS ENOTTY; 1R optional"
fi

if [[ "${resolved}" == *".ko.xz" ]]; then
  echo "FAIL: modprobe resolves to compressed ${resolved}" >&2
  echo "  A stock .ko.xz in updates/ is shadowing the POG422 plain .ko." >&2
  echo "  Fix: bash install_pi.sh   (removes stale .ko.xz, installs fork to updates/)" >&2
  exit 1
fi

if [[ "${resolved}" != "${KO_UPDATES}" ]]; then
  echo "WARN: resolved path is not ${KO_UPDATES}" >&2
  echo "  Expected POG422 fork in updates/ after install_pi.sh." >&2
fi

echo "--- other on-disk copies (informational) ---"
for f in "${KO_UPDATES}" "${KO_UPDATES}.xz" "${KO_EXTRA}" "${KO_EXTRA}.xz"; do
  if [[ -f "${f}" ]]; then
    echo "${f} version=$(ko_built_version "${f}")"
  fi
done

found_marker=0
for m in "${RS485_STRING_MARKERS[@]}"; do
  if strings "${resolved}" | grep -qF "${m}"; then
    echo "OK: resolved .ko strings contain '${m}'"
    found_marker=1
    break
  fi
done
if [[ "${found_marker}" -eq 0 ]]; then
  echo "NOTE: no RS485 debug strings in strings(1) — modinfo version is OK"
fi

echo "--- loaded (sysfs / in RAM) ---"
if lsmod | grep -q "^${MOD}"; then
  lsmod | grep "^${MOD}" || true
  if [[ -r "/sys/module/${MOD}/version" ]]; then
    loaded_ver="$(tr -d '\n' < "/sys/module/${MOD}/version")"
    echo "LOADED: cat /sys/module/${MOD}/version → ${loaded_ver}"
    if [[ "${loaded_ver}" != "${resolved_ver}" ]]; then
      echo "FAIL: STALE MODULE — installed=${resolved_ver} but RUNNING=${loaded_ver}" >&2
      echo "  Plain modinfo lied: disk is newer than RAM." >&2
      echo "  Fix: stop bridge/uartd, UNPLUG hat, then:" >&2
      echo "    sudo modprobe -r ${MOD} && sudo modprobe ${MOD}" >&2
      echo "  REPLUG hat, then re-run: bash verify_driver.sh" >&2
      exit 1
    fi
    if ! driver_version_ok "${loaded_ver}"; then
      echo "FAIL: loaded version ${loaded_ver} not in accepted set" >&2
      exit 1
    elif [[ "${loaded_ver}" == "${MIN_DRIVER}" ]]; then
      echo "NOTE: loaded 1Q — OK with uartd 1.0.52+ (1R optional)"
    elif [[ "${loaded_ver}" != "${PREFERRED_DRIVER}" ]]; then
      echo "WARN: loaded ${loaded_ver} != preferred ${PREFERRED_DRIVER}" >&2
    else
      echo "OK: loaded == installed == ${PREFERRED_DRIVER}"
    fi
  else
    echo "FAIL: /sys/module/${MOD}/version not readable while lsmod shows module" >&2
    exit 1
  fi
else
  echo "FAIL: ${MOD} not loaded — sudo modprobe ${MOD}" >&2
  exit 1
fi

echo "--- device nodes ---"
if ls /dev/ttyXRUSB* >/dev/null 2>&1; then
  ls -l /dev/ttyXRUSB*
  echo "NOTE: ttyXRUSB* exists for stock Exar driver too — use modprobe resolution above, not node names alone"
elif ls /dev/ttyUSB* >/dev/null 2>&1; then
  echo "FAIL: hat on ttyUSB* (in-kernel xr) — sudo /usr/local/sbin/pog422_rebind_xr21.sh" >&2
  exit 1
else
  echo "WARN: no ttyXRUSB* or ttyUSB* — is hat plugged in?"
fi

echo "--- dmesg (POG422 probe + recent GPIO mode) ---"
if sudo dmesg -T 2>/dev/null | grep -i POG422 | tail -5; then
  :
else
  echo "  (no POG422 probe lines — replug hat USB or reboot, then re-run this script)"
fi
echo "Recent set_flow_mode lines:"
sudo dmesg -T 2>/dev/null | grep -E 'GPIO Mode|POG422' | tail -8 || true

if sudo dmesg 2>/dev/null | grep -q "GPIO7 output inactive"; then
  echo "OK: dmesg shows early GPIO7 output inactive (1E boot init)"
elif sudo dmesg 2>/dev/null | grep -qE "POG422 1N|manual GPIO7|1N mixed"; then
  echo "OK: dmesg shows POG422 1N mixed GPIO (MST RS485 auto + SLV manual GPIO7)"
elif sudo dmesg 2>/dev/null | grep -q "GPIO Mode = 339 (POG422 RS485 auto)"; then
  echo "WARN: dmesg shows legacy all-channel RS485 auto — want 1N mixed; reboot after install_pi.sh" >&2
elif sudo dmesg 2>/dev/null | grep -q "GPIO Mode = 300"; then
  echo "OK: dmesg shows GPIO Mode 0x300 on SLV block (manual GPIO7 path)"
else
  echo "NOTE: no GPIO Mode lines in dmesg yet — replug USB or reboot after install_pi.sh"
fi

echo "=== verify OK ==="
