#!/usr/bin/env bash
# ═══════════════════════════════════════════════════════════════════════════
# updates-flow.sh — Demo del flujo de actualización de alloy
# Para el Episodio #834 — atareao con Linux
# ═══════════════════════════════════════════════════════════════════════════
# Muestra el flujo completo: check-all → digest compare → policy apply → SSE
# ═══════════════════════════════════════════════════════════════════════════

set -e

VERDE='\033[0;32m'
AMARILLO='\033[1;33m'
AZUL='\033[0;34m'
ROJO='\033[0;31m'
GRIS='\033[0;90m'
NC='\033[0m'

echo -e "${AZUL}╔══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${AZUL}║  🔄 alloy — Flujo de actualización                          ║${NC}"
echo -e "${AZUL}║  Fase 1: Check (bloqueante, devuelve respuesta)             ║${NC}"
echo -e "${AZUL}║  Fase 2: Policy apply (background, SSE progress)            ║${NC}"
echo -e "${AZUL}╚══════════════════════════════════════════════════════════════╝${NC}"
echo ""

# ── Fase 1: Check ────────────────────────────────────────────────────────
echo -e "${VERDE}═══ Fase 1: Check All ═══${NC}"
echo ""
echo -e "${GRIS}El backend:${NC}"
echo "  1. Obtiene todos los contenedores (fetch_containers)"
echo "  2. Para cada contenedor (en paralelo, semáforo 4 conexiones):"
echo "     a. Parsear referencia de imagen → (registry, repo, tag)"
echo "     b. Solicitar token Bearer a auth.docker.io"
echo "     c. Consultar manifest en registry-1.docker.io/v2/{repo}/manifests/{tag}"
echo "     d. Extraer config.digest del manifest"
echo "     e. Comparar short_digest(local) vs short_digest(remote)"
echo "  3. Persistir has_update en SQLite"
echo "  4. Construir lista de pendientes"
echo "  5. Lanzar apply_policies_background en tokio::spawn"
echo "  6. Devolver respuesta JSON con has_update flags"
echo ""

# ── Fase 2: Policy Apply ─────────────────────────────────────────────────
echo -e "${VERDE}═══ Fase 2: Policy Apply (background) ═══${NC}"
echo ""
echo -e "${GRIS}Para cada contenedor pendiente:${NC}"
echo ""
echo "  ┌─ [PullRestart] ──────────────────────────────────────────────┐"
echo "  │  1. tag_backup_image()  (si rollback_on_failure=true)        │"
echo "  │  2. pull_image() → docker.create_image()                     │"
echo "  │  3. recreate_container() → stop + rename + create + start    │"
echo "  │  4. verify_container_healthy() (si rollback)                 │"
echo "  │     ├── OK → continue                                        │"
echo "  │     └── FAIL → rollback_container() (restaurar imagen)       │"
echo "  │  5. cleanup_old_image() (si cleanup_old_image=true)          │"
echo "  └──────────────────────────────────────────────────────────────┘"
echo ""
echo "  ┌─ [PullRestartStack] ─────────────────────────────────────────┐"
echo "  │  1. resolve_compose_file() → labels del contenedor           │"
echo "  │  2. docker compose -f <file> pull                            │"
echo "  │  3. docker compose -f <file> up -d                           │"
echo "  └──────────────────────────────────────────────────────────────┘"
echo ""
echo "  ┌─ [Pull] ─────────────────────────────────────────────────────┐"
echo "  │  1. pull_image() → solo descargar, sin reiniciar             │"
echo "  └──────────────────────────────────────────────────────────────┘"
echo ""

# ── Políticas ────────────────────────────────────────────────────────────
echo -e "${VERDE}═══ Políticas de actualización ═══${NC}"
echo ""
printf "  %-25s %s\n" "None" "No hacer nada"
printf "  %-25s %s\n" "Pull" "Solo descargar imagen"
printf "  %-25s %s\n" "PullRestart" "Descargar + reiniciar contenedor"
printf "  %-25s %s\n" "PullRestartStack" "Descargar + recrear stack completo"
echo ""

# ── Resolución de políticas ──────────────────────────────────────────────
echo -e "${VERDE}═══ Resolución de políticas ═══${NC}"
echo ""
echo "  1. Se mira el label del contenedor (alloy_update_policy)"
echo "  2. Si no tiene label, se busca en update_policies (SQLite)"
echo "  3. Si no hay política específica, se usa la política global (settings)"
echo "  4. PullRestartStack resuelve el archivo compose desde los labels:"
echo "     a. com.docker.compose.project → nombre del proyecto"
echo "     b. com.docker.compose.config.files → ruta al compose file"
echo "     c. com.docker.compose.working_dir → directorio del proyecto"
echo ""

# ── Rollback ─────────────────────────────────────────────────────────────
echo -e "${VERDE}═══ Rollback automático ═══${NC}"
echo ""
echo -e "${GRIS}Si rollback_on_failure=true y el contenedor no arranca:${NC}"
echo ""
echo "  1. tag_backup_image() → etiqueta la imagen actual como backup"
echo "  2. pull_image() → descarga la nueva imagen"
echo "  3. recreate_container() → crea contenedor con nueva imagen"
echo "  4. verify_container_healthy() → espera a que responda"
echo "     ├── OK → todo bien, cleanup de imagen anterior"
echo "     └── FAIL → rollback:"
echo "           ├── remove contenedor nuevo"
echo "           ├── restaurar nombre del backup"
echo "           ├── restart contenedor con imagen anterior"
echo "           └── notificar fallo"
echo ""

# ── SSE Progress ─────────────────────────────────────────────────────────
echo -e "${VERDE}═══ SSE Progress (tiempo real) ═══${NC}"
echo ""
echo -e "${GRIS}Eventos emitidos durante el proceso:${NC}"
echo ""
echo "  event: update-progress"
echo "  data: {\"container\":\"nginx\",\"status\":\"🔍 PullRestart\",\"done\":false}"
echo ""
echo "  event: update-progress"
echo "  data: {\"container\":\"nginx\",\"status\":\"📥 Pulling...\",\"done\":false}"
echo ""
echo "  event: update-progress"
echo "  data: {\"container\":\"nginx\",\"status\":\"✅ actualizado + reiniciado\",\"done\":true}"
echo ""
echo "  event: notification"
echo "  data: {\"container\":\"nginx\",\"status\":\"🔄 actualizado\",\"timestamp\":\"2026-08-29T12:00:00Z\"}"
echo ""

# ── Comandos curl ────────────────────────────────────────────────────────
echo -e "${VERDE}═══ Comandos para probar ═══${NC}"
echo ""
echo "  # Check individual"
echo "  curl -X POST http://localhost:3066/api/check-update/nginx \\"
echo "    -H \"Cookie: session=TU_TOKEN\""
echo ""
echo "  # Update individual"
echo "  curl -X POST http://localhost:3066/api/update/nginx \\"
echo "    -H \"Cookie: session=TU_TOKEN\""
echo ""
echo "  # Check All (masivo)"
echo "  curl -X POST http://localhost:3066/api/check-all \\"
echo "    -H \"Cookie: session=TU_TOKEN\""
echo ""
echo "  # SSE updates (tiempo real)"
echo "  curl -N http://localhost:3066/api/updates \\"
echo "    -H \"Cookie: session=TU_TOKEN\""
echo ""
echo "  # Historial"
echo "  curl http://localhost:3066/api/history \\"
echo "    -H \"Cookie: session=TU_TOKEN\""
echo ""