#!/usr/bin/env bash
# =============================================================================
# runpod-gpu-models-sync.sh — baja a /workspace/ComfyUI/models lo que falte del manifiesto
#
# Lo llama boot.sh en cada arranque y se puede correr a mano por SSH:
#   curl -fsSL https://dl.ramsesvii.com/runpod-gpu-models-sync.sh | bash
# Manifiesto: runpod-gpu-models.txt  (repo_hf | archivo | carpeta [| nombre_local])
# Usa HF_TOKEN del entorno si existe (repos gated). Loguea cada fallo con su motivo en
# /workspace/models-sync.log; nunca borra nada.
# =============================================================================
set -u
W=/workspace; COMFY=$W/ComfyUI; ST=$W/status
DL="${GPU_MANIFEST_BASE:-https://dl.ramsesvii.com}"
LOG=$W/models-sync.log
export HF_HUB_ENABLE_HF_TRANSFER=1 HF_HOME="${HF_HOME:-$W/hf-cache}"
say() { echo "[$(date -u +%FT%TZ)] $*" | tee -a "$LOG"; }

HF="$W/venv/bin/hf"; [ -x "$HF" ] || HF="$W/venv/bin/huggingface-cli"; [ -x "$HF" ] || HF="$(command -v hf || command -v huggingface-cli || true)"
[ -n "$HF" ] || { say "ERROR: no hay cliente hf; pip install 'huggingface_hub[cli]'"; exit 1; }

MODELS=$(curl -fsSL "$DL/runpod-gpu-models.txt" 2>/dev/null || true)
[ -n "$MODELS" ] || { say "ERROR: no pude leer el manifiesto"; exit 1; }

missing=0; failed=0; got=0
while IFS='|' read -r repo rfile dest name; do
  repo="$(echo "${repo%%#*}" | xargs)"; [ -z "$repo" ] && continue
  rfile="$(echo "$rfile" | xargs)"; dest="$(echo "$dest" | xargs)"; name="$(echo "${name:-}" | xargs)"
  [ -n "$name" ] || name="$(basename "$rfile")"
  out="$COMFY/models/$dest/$name"
  [ -f "$out" ] && continue
  missing=$((missing+1))
  [ -f "$ST/phase" ] && [ "$(cat "$ST/phase")" != "ready" ] && echo downloading-models >"$ST/phase"
  say "bajando $name  ($repo/$rfile)"
  mkdir -p "$COMFY/models/$dest"
  tmp="$COMFY/models/$dest/.hfdl-$$"; rm -rf "$tmp"
  if "$HF" download "$repo" "$rfile" --local-dir "$tmp" >"$tmp.out" 2>&1 && [ -f "$tmp/$rfile" ]; then
    mv "$tmp/$rfile" "$out" && rm -rf "$tmp" "$tmp.out" && got=$((got+1)) && say "  ok $(du -h "$out" | cut -f1)"
  else
    failed=$((failed+1)); say "  FALLÓ $name: $(grep -v '^$' "$tmp.out" | tail -2 | tr '\n' ' ' | cut -c1-300)"
    rm -rf "$tmp" "$tmp.out"
  fi
done <<<"$MODELS"
say "resumen: faltaban $missing, bajados $got, fallidos $failed"
[ "$failed" -eq 0 ]
