#!/usr/bin/env bash
#
# FDP PoC 검증 — 단계 2: smrc 환경 audit
#
# 목적: NVMe FDP 파라미터(RUH/RG 개수), toolchain, 디바이스 권한, 디스크 공간을
#       한 번에 수집한다. 측정(단계 4)의 입력값(용량 C, handle 수 N, write 대역폭)을
#       여기서 확정한다.
#
# 사용법:
#   1) 아래 NVME_DEV / NVME_NS 를 실제 경로로 교체 (sudo nvme list 로 확인)
#   2) bash precheck.sh
#   3) 마지막에 출력되는 tar 명령으로 fdp_audit.tar.gz 를 만들어 로컬로 복사
#
# 안전: 이 스크립트는 읽기 전용 조회만 한다. blkdiscard / write 는 하지 않는다.

set -u

# ────────────────────────────────────────────────────────────────
# 0) 디바이스 경로 — 실제 환경에 맞게 교체
# ────────────────────────────────────────────────────────────────
export NVME_DEV="${NVME_DEV:-/dev/nvme0}"      # 컨트롤러 (FDP target: S77UNG0TC00101)
export NVME_NS="${NVME_NS:-/dev/nvme0n1}"      # 네임스페이스 (FDP target: S77UNG0TC00101)
export NVME_NSID="${NVME_NSID:-1}"             # nvme list Namespace 0x1
export FDP_ENDGRP_ID="${FDP_ENDGRP_ID:-1}"     # id-ns의 Endurance Group Identifier와 맞춰 조정
export OUT="${OUT:-$HOME/fdp_audit}"

mkdir -p "$OUT/raw"
echo "[precheck] NVME_DEV=$NVME_DEV  NVME_NS=$NVME_NS  NVME_NSID=$NVME_NSID  FDP_ENDGRP_ID=$FDP_ENDGRP_ID  OUT=$OUT"
echo "[precheck] 시작: $(date -Is)"

# 조회 명령을 실행하고 실패해도 멈추지 않게 감싸는 헬퍼
run() {
  # $1 = 출력파일, 나머지 = 명령
  local out="$1"; shift
  echo "  -> $* "
  if "$@" >"$out" 2>&1; then :; else echo "    (실패/미지원 — 파일에 stderr 기록)"; fi
}

# ────────────────────────────────────────────────────────────────
# 1) 커널 + 디바이스 식별
# ────────────────────────────────────────────────────────────────
run "$OUT/raw/uname.txt"      uname -a
run "$OUT/raw/nvme_list.txt"  sudo nvme list
run "$OUT/raw/nvme_idctrl.txt" sudo nvme id-ctrl "$NVME_DEV"
# 용량(C) 산출용 — NVM capacity / namespace size
run "$OUT/raw/nvme_idns.txt"  sudo nvme id-ns "$NVME_NS"

# ────────────────────────────────────────────────────────────────
# 2) FDP 파라미터 — handle(RUH) 수, RG, 사용량/통계 baseline
#    R2 의 placement 정책(prompt_id % N)에서 N = RUH 수
# ────────────────────────────────────────────────────────────────
run "$OUT/raw/nvme_fdp_configs.txt"        sudo nvme fdp configs "$NVME_DEV" --endgrp-id="$FDP_ENDGRP_ID"
run "$OUT/raw/nvme_fdp_status.txt"         sudo nvme fdp status "$NVME_DEV" --namespace-id="$NVME_NSID"
run "$OUT/raw/nvme_fdp_stats_baseline.txt" sudo nvme fdp stats "$NVME_DEV" --endgrp-id="$FDP_ENDGRP_ID"
run "$OUT/raw/nvme_fdp_usage.txt"          sudo nvme fdp usage "$NVME_DEV" --endgrp-id="$FDP_ENDGRP_ID"
# WAF 계산 기준선 — data_units_written
run "$OUT/raw/nvme_smart_baseline.txt"     sudo nvme smart-log "$NVME_NS"

# ────────────────────────────────────────────────────────────────
# 3) toolchain — PoC 빌드(단계 3) 가능 여부
# ────────────────────────────────────────────────────────────────
{
  echo "=== rustc ==="    ; rustc --version 2>&1
  echo "=== cargo ==="    ; cargo --version 2>&1
  echo "=== maturin ===" ; maturin --version 2>&1 || echo "missing"
  echo "=== python ==="   ; python3 --version 2>&1
  echo "=== liburing ===" ; pkg-config --modversion liburing 2>&1 || echo "missing"
  echo "=== nvme-cli ===" ; nvme version 2>&1
  echo "=== gcc ==="      ; gcc --version 2>&1 | head -1
  echo "=== nvidia-smi ===" ; nvidia-smi -L 2>&1 | head -5 || echo "no gpu / driver"
} > "$OUT/raw/toolchain.txt"

# ────────────────────────────────────────────────────────────────
# 4) 권한 — raw block 접근, mount 상태, blkdiscard 가용 여부
#    (측정 반복에 blkdiscard 권한 필요 — 여기선 확인만, 실행 안 함)
# ────────────────────────────────────────────────────────────────
{
  echo "=== block device perms ==="; ls -l "$NVME_NS"
  echo "=== mount status ==="
  if mount | grep -i "$(basename "$NVME_NS")"; then :; else echo "not mounted"; fi
  echo "=== blkdiscard available? ==="; command -v blkdiscard && blkdiscard --help 2>&1 | head -3 || echo "blkdiscard missing"
} > "$OUT/raw/permissions.txt"

# ────────────────────────────────────────────────────────────────
# 5) 디스크 공간 — file backend 대안 경로 검토용
# ────────────────────────────────────────────────────────────────
run "$OUT/raw/df.txt" df -h "$HOME"

# ────────────────────────────────────────────────────────────────
# 6) Vendor media-write counter 후보 탐색
#    PoC WAF = media_write_bytes / host_write_bytes 이므로 vendor counter가
#    있으면 config의 measurement.vendor_media_write_command로 연결한다.
# ────────────────────────────────────────────────────────────────
{
  echo "=== nvme smart-log standard (host write counter source) ==="
  sudo nvme smart-log "$NVME_NS" -o json 2>&1 | head -40

  echo "=== nvme smart-log-add (generic / vendor extension) ==="
  sudo nvme smart-log-add "$NVME_NS" 2>&1 | head -40

  echo "=== nvme samsung vs-smart-add-log ==="
  sudo nvme samsung vs-smart-add-log "$NVME_NS" 2>&1 | head -40

  echo "=== nvme ocp smart-add-log ==="
  sudo nvme ocp smart-add-log "$NVME_NS" 2>&1 | head -60

  echo "=== nvme get-log vendor pages 0xC0 / 0xCA ==="
  sudo nvme get-log "$NVME_NS" --log-id=0xC0 --log-len=512 2>&1 | head -20
  sudo nvme get-log "$NVME_NS" --log-id=0xCA --log-len=512 2>&1 | head -20

  echo "=== nvme list-plugins ==="
  sudo nvme list-plugins 2>&1
} > "$OUT/raw/media_write_counter_probe.txt" 2>&1

# ────────────────────────────────────────────────────────────────
# 7) xnvme probe — PoC harness의 FDP log 수집 경로
# ────────────────────────────────────────────────────────────────
{
  echo "=== xnvme version ==="; xnvme --version 2>&1 || echo "missing"
  echo "=== xnvme log-fdp-stats ==="; sudo xnvme log-fdp-stats "$NVME_NS" --lsi 0x1 2>&1 | head -20
  echo "=== xnvme fdp-ruhs ==="; sudo xnvme fdp-ruhs "$NVME_NS" --limit 16 2>&1 | head -20
} > "$OUT/raw/xnvme_probe.txt" 2>&1

echo "[precheck] 완료: $(date -Is)"
echo
echo "──────────────────────────────────────────────────────"
echo " 다음: 아래 명령으로 압축 후 로컬로 복사하세요."
echo "   tar czf fdp_audit.tar.gz -C \"$HOME\" fdp_audit"
echo " 로컬 복사 위치: private/work/fdp/02_smrc_env/raw/"
echo "──────────────────────────────────────────────────────"
echo
echo " 핵심 확인 포인트(Codex가 정리할 입력):"
echo "   - nvme_idns.txt        → 용량 C (NVM capacity), Endurance Group Identifier 확인"
echo "   - nvme_fdp_configs.txt  → handle 수 N (RUH 개수). 실패 시 FDP_ENDGRP_ID 재설정"
echo "   - nvme_fdp_status.txt   → FDP enabled 여부"
echo "   - toolchain.txt         → rustc/maturin/liburing 빌드 의존성"
echo "   - permissions.txt       → blkdiscard 권한 (측정 반복 가능 여부)"
