#!/usr/bin/env bash
# =============================================================================
# COCONEWS - Diagnóstico del sistema
# Verifica que todos los servicios estén OK y muestra estado + sugerencias
#
# Uso:
#   bash deploy/debian/check.sh           # diagnóstico completo
#   bash deploy/debian/check.sh --quick   # solo servicios arriba/abajo
# =============================================================================

RSS2_HOME="/opt/rss2"
API_PORT="8080"
QUICK=false
[[ "${1:-}" == "--quick" ]] && QUICK=true

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
BLUE='\033[0;34m'; BOLD='\033[1m'; DIM='\033[2m'; NC='\033[0m'
CYAN='\033[0;36m'

OK()   { echo -e "  ${GREEN}[✓]${NC} $*"; }
FAIL() { echo -e "  ${RED}[✗]${NC} $*"; }
WARN() { echo -e "  ${YELLOW}[!]${NC} $*"; }
INFO() { echo -e "  ${DIM}    $*${NC}"; }
HEAD() { echo -e "\n${BOLD}${CYAN}── $* ${NC}"; }
FIX()  { echo -e "  ${YELLOW}    → Fix:${NC} $*"; }

ERRORS=0
WARNINGS=0

fail_with_fix() {
    FAIL "$1"
    shift
    for fix in "$@"; do FIX "$fix"; done
    (( ERRORS++ )) || true
}

warn_with_fix() {
    WARN "$1"
    shift
    for fix in "$@"; do FIX "$fix"; done
    (( WARNINGS++ )) || true
}

echo ""
echo -e "${BOLD}╔═══════════════════════════════════════════╗${NC}"
echo -e "${BOLD}║     COCONEWS · Diagnóstico del Sistema    ║${NC}"
echo -e "${BOLD}╚═══════════════════════════════════════════╝${NC}"
echo -e "${DIM}$(date '+%Y-%m-%d %H:%M:%S') · $(hostname)${NC}"

# =============================================================================
# 1. SERVICIOS SYSTEMD
# =============================================================================
HEAD "Servicios systemd"

GO_SERVICES=(
    "rss2-backend:API REST Go"
    "rss2-ingestor:Ingestor RSS"
    "rss2-scraper:Scraper HTML"
    "rss2-discovery:Discovery de feeds"
    "rss2-wiki:Wiki worker"
    "rss2-topics:Topics matcher"
    "rss2-related:Related news"
    "rss2-qdrant-worker:Qdrant sync"
)
PY_SERVICES=(
    "rss2-langdetect:Detección de idioma"
    "rss2-translation-scheduler:Scheduler traducción"
    "rss2-translator:Traductor NLLB-200"
    "rss2-embeddings:Embeddings ML"
    "rss2-ner:NER entidades"
    "rss2-cluster:Clustering eventos"
    "rss2-categorizer:Categorizador"
)
INFRA_SERVICES=(
    "rss2-qdrant:Vector DB Qdrant"
    "postgresql:PostgreSQL"
    "redis-server:Redis"
    "nginx:Nginx"
)

check_service() {
    local svc="${1%%:*}"
    local name="${1##*:}"
    if ! command -v systemctl &>/dev/null; then
        WARN "$name (systemctl no disponible)"
        return
    fi
    local state
    state=$(systemctl is-active "$svc" 2>/dev/null || echo "unknown")
    case "$state" in
        active)
            OK "$name ($svc)"
            ;;
        failed)
            fail_with_fix "$name ($svc) — FAILED" \
                "journalctl -u $svc -n 30 --no-pager" \
                "systemctl restart $svc"
            ;;
        inactive)
            warn_with_fix "$name ($svc) — inactivo" \
                "systemctl start $svc" \
                "systemctl enable $svc"
            ;;
        *)
            warn_with_fix "$name ($svc) — $state" \
                "systemctl status $svc"
            ;;
    esac
}

echo -e "\n  ${DIM}Infraestructura:${NC}"
for svc in "${INFRA_SERVICES[@]}"; do check_service "$svc"; done

echo -e "\n  ${DIM}Workers Go:${NC}"
for svc in "${GO_SERVICES[@]}"; do check_service "$svc"; done

echo -e "\n  ${DIM}Workers Python (ML):${NC}"
for svc in "${PY_SERVICES[@]}"; do check_service "$svc"; done

[[ "$QUICK" == "true" ]] && {
    echo ""
    [[ "$ERRORS" -eq 0 && "$WARNINGS" -eq 0 ]] && \
        echo -e "  ${GREEN}${BOLD}Todo OK${NC}" || \
        echo -e "  ${RED}Errores: $ERRORS  ${YELLOW}Advertencias: $WARNINGS${NC}"
    exit 0
}

# =============================================================================
# 2. CONECTIVIDAD
# =============================================================================
HEAD "Conectividad"

# PostgreSQL
PG_ENV="$RSS2_HOME/.env"
if [[ -f "$PG_ENV" ]]; then
    source "$PG_ENV" 2>/dev/null || true
fi
DB_NAME="${POSTGRES_DB:-rss}"
DB_USER="${POSTGRES_USER:-rss}"

if pg_isready -q 2>/dev/null; then
    OK "PostgreSQL acepta conexiones"
    # Probar conexión con usuario rss2
    if sudo -u postgres psql -d "$DB_NAME" -c "SELECT 1" &>/dev/null 2>&1; then
        NEWS=$(sudo -u postgres psql -tq -d "$DB_NAME" \
            -c "SELECT COUNT(*) FROM noticias;" 2>/dev/null | tr -d ' \n' || echo "?")
        TRANS=$(sudo -u postgres psql -tq -d "$DB_NAME" \
            -c "SELECT COUNT(*) FROM traducciones WHERE status='done';" 2>/dev/null | tr -d ' \n' || echo "?")
        PEND=$(sudo -u postgres psql -tq -d "$DB_NAME" \
            -c "SELECT COUNT(*) FROM traducciones WHERE status='pending';" 2>/dev/null | tr -d ' \n' || echo "?")
        INFO "Base de datos: $DB_NAME"
        INFO "Noticias: $NEWS  |  Traducciones hechas: $TRANS  |  Pendientes: $PEND"
    else
        warn_with_fix "No se puede conectar a la BD '$DB_NAME' con usuario '$DB_USER'" \
            "sudo -u postgres psql -c \"\\du\"  # listar usuarios" \
            "Revisa DB_USER y DB_PASS en $RSS2_HOME/.env"
    fi
else
    fail_with_fix "PostgreSQL no responde" \
        "sudo systemctl start postgresql" \
        "sudo journalctl -u postgresql -n 20 --no-pager" \
        "sudo pg_ctlcluster 16 main status"
fi

# Redis
REDIS_PASS="${REDIS_PASSWORD:-}"
REDIS_AUTH=""
[[ -n "$REDIS_PASS" ]] && REDIS_AUTH="-a $REDIS_PASS"
if redis-cli $REDIS_AUTH ping 2>/dev/null | grep -q PONG; then
    REDIS_MEM=$(redis-cli $REDIS_AUTH info memory 2>/dev/null | grep used_memory_human | cut -d: -f2 | tr -d '\r' || echo "?")
    OK "Redis responde (memoria usada: ${REDIS_MEM})"
else
    fail_with_fix "Redis no responde" \
        "sudo systemctl start redis-server" \
        "redis-cli ping  # sin auth" \
        "Verifica REDIS_PASSWORD en $RSS2_HOME/.env"
fi

# Qdrant
if curl -sf "http://127.0.0.1:6333/healthz" &>/dev/null; then
    QDRANT_VER=$(curl -sf "http://127.0.0.1:6333/" 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('version','?'))" 2>/dev/null || echo "?")
    OK "Qdrant responde (v${QDRANT_VER})"
else
    warn_with_fix "Qdrant no responde en :6333" \
        "systemctl start rss2-qdrant" \
        "journalctl -u rss2-qdrant -n 20 --no-pager" \
        "Búsqueda semántica no funcionará hasta que Qdrant esté activo"
fi

# API Backend Go
if curl -sf "http://127.0.0.1:${API_PORT}/api/stats" &>/dev/null; then
    STATS=$(curl -sf "http://127.0.0.1:${API_PORT}/api/stats" 2>/dev/null | \
        python3 -c "import sys,json; d=json.load(sys.stdin); print(f\"noticias={d.get('total_news','?')} feeds={d.get('total_feeds','?')}\")" 2>/dev/null || echo "")
    OK "API backend responde (:${API_PORT}) — $STATS"
else
    fail_with_fix "API backend no responde en :${API_PORT}" \
        "systemctl restart rss2-backend" \
        "journalctl -u rss2-backend -n 30 --no-pager" \
        "curl http://127.0.0.1:${API_PORT}/api/stats  # prueba manual"
fi

# Nginx
if curl -sf "http://127.0.0.1:8001/health" &>/dev/null; then
    OK "Nginx responde (:8001)"
else
    fail_with_fix "Nginx no responde en :8001" \
        "nginx -t  # verificar config" \
        "systemctl restart nginx" \
        "journalctl -u nginx -n 20 --no-pager"
fi

# =============================================================================
# 3. BINARIOS GO
# =============================================================================
HEAD "Binarios compilados"

BINS=(server ingestor scraper discovery wiki_worker topics related qdrant_worker)
for bin in "${BINS[@]}"; do
    BIN_PATH="$RSS2_HOME/bin/$bin"
    if [[ -x "$BIN_PATH" ]]; then
        SIZE=$(du -sh "$BIN_PATH" 2>/dev/null | cut -f1)
        OK "$bin (${SIZE})"
    else
        fail_with_fix "$bin no encontrado o sin permisos de ejecución en $BIN_PATH" \
            "sudo bash deploy/debian/build.sh  # recompila todos los binarios"
    fi
done

# =============================================================================
# 4. MODELOS ML
# =============================================================================
HEAD "Modelos ML"

# NLLB-200 CTranslate2
if [[ -d "$RSS2_HOME/models/nllb-ct2" ]] && \
   [[ -f "$RSS2_HOME/models/nllb-ct2/model.bin" ]]; then
    SIZE=$(du -sh "$RSS2_HOME/models/nllb-ct2" 2>/dev/null | cut -f1)
    OK "NLLB-200 CTranslate2 (${SIZE})"
else
    warn_with_fix "Modelo NLLB-200 no encontrado en $RSS2_HOME/models/nllb-ct2" \
        "El traductor no funcionará hasta que esté el modelo" \
        "Convierte con: ver sección 3 de DEPLOY_DEBIAN.md"
fi

# spaCy
if "$RSS2_HOME/venv/bin/python" -c "import spacy; spacy.load('es_core_news_lg')" &>/dev/null 2>&1; then
    OK "spaCy es_core_news_lg"
else
    warn_with_fix "Modelo spaCy es_core_news_lg no disponible" \
        "$RSS2_HOME/venv/bin/python -m spacy download es_core_news_lg" \
        "El worker NER no funcionará hasta instalarlo"
fi

# sentence-transformers (embeddings)
if "$RSS2_HOME/venv/bin/python" -c "from sentence_transformers import SentenceTransformer" &>/dev/null 2>&1; then
    OK "sentence-transformers disponible"
else
    warn_with_fix "sentence-transformers no instalado" \
        "$RSS2_HOME/venv/bin/pip install sentence-transformers==3.0.1" \
        "Los embeddings y búsqueda semántica no funcionarán"
fi

# ctranslate2
if "$RSS2_HOME/venv/bin/python" -c "import ctranslate2" &>/dev/null 2>&1; then
    OK "ctranslate2 disponible"
else
    warn_with_fix "ctranslate2 no instalado" \
        "$RSS2_HOME/venv/bin/pip install ctranslate2>=4.0.0" \
        "La traducción NLLB-200 no funcionará"
fi

# =============================================================================
# 5. DISCO Y PERMISOS
# =============================================================================
HEAD "Disco y permisos"

# Espacio en disco
DISK_FREE=$(df -h "$RSS2_HOME" 2>/dev/null | tail -1 | awk '{print $4}')
DISK_PCT=$(df "$RSS2_HOME" 2>/dev/null | tail -1 | awk '{print $5}' | tr -d '%')
if [[ "${DISK_PCT:-0}" -gt 90 ]]; then
    fail_with_fix "Disco al ${DISK_PCT}% — quedan solo ${DISK_FREE}" \
        "du -sh $RSS2_HOME/* | sort -rh | head -10  # ver qué ocupa más" \
        "Los modelos ML necesitan ~5 GB libres"
elif [[ "${DISK_PCT:-0}" -gt 75 ]]; then
    warn_with_fix "Disco al ${DISK_PCT}% (libre: ${DISK_FREE})" \
        "Revisa el espacio antes de descargar modelos ML"
else
    OK "Disco: ${DISK_PCT}% usado, ${DISK_FREE} libres"
fi

# Permisos de /opt/rss2
if [[ -d "$RSS2_HOME" ]]; then
    OWNER=$(stat -c '%U' "$RSS2_HOME" 2>/dev/null || echo "?")
    if [[ "$OWNER" == "rss2" ]]; then
        OK "Propietario de $RSS2_HOME: rss2"
    else
        warn_with_fix "Propietario de $RSS2_HOME es '$OWNER', debería ser 'rss2'" \
            "sudo chown -R rss2:rss2 $RSS2_HOME"
    fi
fi

# .env
if [[ -f "$RSS2_HOME/.env" ]]; then
    ENV_PERMS=$(stat -c '%a' "$RSS2_HOME/.env" 2>/dev/null || echo "?")
    if [[ "$ENV_PERMS" == "600" ]]; then
        OK ".env con permisos 600 (correcto)"
    else
        warn_with_fix ".env con permisos ${ENV_PERMS} (debería ser 600)" \
            "chmod 600 $RSS2_HOME/.env"
    fi
    # Verificar que no quedan valores por defecto peligrosos
    if grep -q "CAMBIA_ESTO\|changeme\|change_this" "$RSS2_HOME/.env" 2>/dev/null; then
        warn_with_fix ".env tiene valores por defecto sin cambiar" \
            "nano $RSS2_HOME/.env  # cambia POSTGRES_PASSWORD, REDIS_PASSWORD, SECRET_KEY"
    fi
else
    fail_with_fix ".env no encontrado en $RSS2_HOME/.env" \
        "cp deploy/debian/env.example $RSS2_HOME/.env" \
        "nano $RSS2_HOME/.env  # edita contraseñas"
fi

# =============================================================================
# RESUMEN FINAL
# =============================================================================
echo ""
echo -e "${BOLD}══════════════════════════════════════════════${NC}"
if [[ "$ERRORS" -eq 0 && "$WARNINGS" -eq 0 ]]; then
    echo -e "  ${GREEN}${BOLD}Sistema OK — todo funcionando correctamente${NC}"
elif [[ "$ERRORS" -eq 0 ]]; then
    echo -e "  ${YELLOW}${BOLD}Sistema funcional con $WARNINGS advertencia(s)${NC}"
    echo -e "  ${DIM}Las advertencias no bloquean el funcionamiento básico${NC}"
else
    echo -e "  ${RED}${BOLD}$ERRORS error(es) encontrado(s)${YELLOW}  $WARNINGS advertencia(s)${NC}"
    echo -e "  ${DIM}Sigue los fixes indicados arriba para resolverlos${NC}"
fi
echo -e "${BOLD}══════════════════════════════════════════════${NC}"
echo ""
echo -e "  ${DIM}Logs de servicios: journalctl -u rss2-backend -f${NC}"
echo -e "  ${DIM}Diagnóstico rápido: bash deploy/debian/check.sh --quick${NC}"
echo ""

exit $(( ERRORS > 0 ? 1 : 0 ))
