#!/usr/bin/env bash
# edge-1 eMMC wear/health check. Managed by roles/edge-flash-wear.
#
# Reads the JEDEC eMMC 5.x life-time and pre-EOL estimators exposed via sysfs
# and emits a warning-priority journal message when the flash leaves the
# healthy band. Run weekly by edge-emmc-health.timer. No arguments; it
# auto-detects the eMMC backing the root filesystem.
set -euo pipefail

root_src="$(findmnt -no SOURCE /)"
disk="$(lsblk -no PKNAME "$root_src" 2>/dev/null || true)"
[ -z "$disk" ] && disk="$(basename "$root_src")"
sys="/sys/block/${disk}/device"

if [ ! -e "$sys/life_time" ]; then
  echo "no eMMC life_time attribute for /dev/$disk (not an eMMC?) — nothing to check"
  exit 0
fi

read -r lt_a lt_b < "$sys/life_time"
pre_eol="$(cat "$sys/pre_eol_info" 2>/dev/null || echo 0x00)"

# JEDEC DEVICE_LIFE_TIME_EST_TYP_A/B: 0x01=0-10% consumed ... 0x0A=90-100%,
# 0x0B=exceeded. pre_eol: 0x01=normal, 0x02=warning (80% reserve used),
# 0x03=urgent (90% reserve used).
band() {
  case "${1,,}" in
    0x01) echo "0-10%";;   0x02) echo "10-20%";;  0x03) echo "20-30%";;
    0x04) echo "30-40%";;  0x05) echo "40-50%";;  0x06) echo "50-60%";;
    0x07) echo "60-70%";;  0x08) echo "70-80%";;  0x09) echo "80-90%";;
    0x0a) echo "90-100%";; 0x0b) echo ">100% (exceeded)";;
    *)    echo "unknown ($1)";;
  esac
}
eol_txt() {
  case "${1,,}" in
    0x00) echo "not-defined";;
    0x01) echo "normal";;
    0x02) echo "WARNING (80% reserved blocks consumed)";;
    0x03) echo "URGENT (90% reserved blocks consumed)";;
    *)    echo "unknown ($1)";;
  esac
}

msg="eMMC /dev/$disk: life_time A=$(band "$lt_a") B=$(band "$lt_b"), pre_eol=$(eol_txt "$pre_eol")"
echo "$msg"

# Healthy = both estimators in the first band and pre-EOL normal/undefined.
worn=0
case "${lt_a,,}"    in 0x01) ;; *) worn=1;; esac
case "${lt_b,,}"    in 0x01) ;; *) worn=1;; esac
case "${pre_eol,,}" in 0x00|0x01) ;; *) worn=1;; esac

if [ "$worn" -ne 0 ]; then
  echo "$msg" | systemd-cat -t edge-emmc-health -p warning
fi
