#!/usr/bin/env bash
# =============================================================================
#  demo-03 · La prueba del ciudadano
# =============================================================================
#  A qué punto del guion sirve: punto 15
#    «Qué puedes hacer tú: prueba, mide y denuncia»
#
#  Qué hace: cuando un sitio legítimo te falla, guarda la prueba CON FECHA en un
#  fichero fechado. Dominio, operador, hora exacta y el error tal cual.
#    · curl  → ¿responde? ¿con qué código? ¿cuánto tarda? y el error completo.
#    · dig   → ¿resuelve? ¿a qué direcciones? ¿con qué servidor de nombres?
#    · whois → ¿de quién es esa dirección? (si es de un rango compartido, no se
#              ha caído «tu» servidor: se ha caído un vector que usan cientos de
#              miles de sitios). Si no hay `whois` instalado, se usa RDAP con
#              `curl`, que da la misma información sin instalar nada.
#
#  Uso:
#      ./demo-03-prueba-del-ciudadano.sh <dominio> [operador]
#      ./demo-03-prueba-del-ciudadano.sh tudominio.example "Mi operador"
#
#  El informe se guarda en:
#      $PRUEBAS_DIR/<AAAA-MM-DD_HHMMSS>-prueba-<dominio>.txt
#      (por defecto $PRUEBAS_DIR=/tmp/opencode/pruebas-ciudadano)
#
#  Códigos de salida (para que sirva también en un cron o en un script):
#      0 = el sitio responde
#      1 = el sitio NO responde (conexión, TLS o tiempo agotado)
#      2 = el nombre no resuelve
#      3 = no se ha podido escribir el informe
#
#  Estado: VERIFICADO en local (cuatro casos: responde, no resuelve, no responde
#  y bloqueo detectado). Salidas reales en `verificacion/demo-03-*.txt`.
#
#  Seguridad de la demo: solo lectura. Nada de `ssh`, nada de tocar servidores
#  ajenos, nada que modifique el sistema. El único tráfico que sale es el de tus
#  propias consultas DNS/HTTP, que es justo lo que se está probando.
# =============================================================================

set -u

DOMINIO="${1:-example.com}"
OPERADOR="${2:-${OPERADOR:-(anota aquí tu operador: Movistar, Vodafone, Digi…)}}"
DESTINO="${PRUEBAS_DIR:-/tmp/opencode/pruebas-ciudadano}"

if [ "$DOMINIO" = "-h" ] || [ "$DOMINIO" = "--help" ]; then
    sed -n '2,32p' "$0" | sed 's/^# \{0,1\}//'
    exit 0
fi

mkdir -p "$DESTINO" || { printf 'no se puede crear %s\n' "$DESTINO" >&2; exit 3; }
FECHA="$(date +%Y-%m-%d_%H%M%S)"
INFORME="$DESTINO/${FECHA}-prueba-${DOMINIO}.txt"
: > "$INFORME" || exit 3

ULTIMO_RC=0
salida()  { printf '%s\n' "$*" | tee -a "$INFORME"; }
orden()   { printf '\n$ %s\n' "$*" | tee -a "$INFORME"; }
run() {     # run <comando…>  → lanza, guarda la salida y el código, nunca aborta
    local cabecera salida_cmd rc=0
    cabecera="$(printf '$'; for a in "$@"; do
        case "$a" in
            *" "*) printf " '%s'" "$a" ;;
            *)     printf ' %s' "$a" ;;
        esac
    done)"
    printf '\n%s\n' "$cabecera" | tee -a "$INFORME"
    salida_cmd="$("$@" 2>&1)" || rc=$?
    printf '%s\n' "$salida_cmd" | tee -a "$INFORME"
    if [ "$rc" -ne 0 ]; then printf '[exit %s]\n' "$rc" | tee -a "$INFORME"; fi
    ULTIMO_RC=$rc
    return 0
}

# ------------------------------------------------------------------ cabecera
salida "================================================================"
salida " PRUEBA DE ACCESO — prueba del ciudadano"
salida "================================================================"
salida " Dominio   : $DOMINIO"
salida " Operador  : $OPERADOR"
salida " Fecha     : $(date -Is)"
salida " Equipo    : $(hostname) · $(uname -sr)"
salida "================================================================"
salida ""
salida "Nota: esta prueba NO dice quién bloquea ni por qué. Solo deja constancia"
salida "fechada de lo que ha pasado desde tu conexión. Una prueba, o varias, es"
salida "lo que se adjunta a una reclamación."

# --------------------------------------------------------------- 1 · curl
salida ""
salida "--- 1 · ¿El sitio responde? -------------------------------------"
if command -v curl >/dev/null 2>&1; then
    run curl -sS -o /dev/null \
        --connect-timeout 10 --max-time 20 \
        -w 'HTTP %{http_code} · connect %{time_connect}s · TLS %{time_appconnect}s · total %{time_total}s · IP destino %{remote_ip}\n' \
        "https://$DOMINIO/"
    RC_CURL=$ULTIMO_RC
    orden "curl -v https://$DOMINIO/   # el error tal cual, para adjuntar"
    curl -v -o /dev/null --connect-timeout 10 --max-time 20 "https://$DOMINIO/" 2>&1 \
        | tee -a "$INFORME"
else
    salida "curl no está instalado: sin esta parte no hay prueba de acceso."
    RC_CURL=127
fi

# --------------------------------------------------------------- 2 · dig
salida ""
salida "--- 2 · ¿Resuelve el nombre? ------------------------------------"
IP_A=""
if command -v dig >/dev/null 2>&1; then
    run dig "$DOMINIO" A
    IP_A="$(dig +short A "$DOMINIO" | grep -E '^[0-9.]+$' | head -1)"
    run dig +short "$DOMINIO" AAAA
    run dig +short "$DOMINIO" NS
    if [ -n "$IP_A" ]; then
        salida ""
        salida "Primera dirección IPv4 anotada: $IP_A"
    fi
else
    salida "dig no está instalado (paquete bind-utils / dnsutils)."
fi

# --------------------------------------------------------------- 3 · whois
salida ""
salida "--- 3 · ¿De quién es esa dirección? -----------------------------"
salida "(si es de un rango compartido, no está caído «tu» servidor:"
salida " está caído un vector que usan cientos de miles de sitios)"
if [ -z "$IP_A" ]; then
    salida "Sin dirección IPv4 no hay nada que consultar."
elif command -v whois >/dev/null 2>&1; then
    run whois "$IP_A"
else
    salida "No hay 'whois' instalado en este equipo. Alternativa sin instalar nada:"
    salida "RDAP, el registro de direcciones que habla HTTP."
    if command -v curl >/dev/null 2>&1; then
        orden "curl -sSL https://rdap.org/ip/$IP_A"
        RDAP="$(curl -sSL --connect-timeout 10 --max-time 20 "https://rdap.org/ip/$IP_A" 2>&1)" \
            || salida "(la consulta RDAP ha fallado)"
        if command -v jq >/dev/null 2>&1 && printf '%s' "$RDAP" | jq -e . >/dev/null 2>&1; then
            printf '%s' "$RDAP" | jq -r '
                "  titular   : " + (.name // .handle // (.entities[0].handle // "?")),
                "  registro  : " + (.handle // "?"),
                "  país      : " + (.country // "?"),
                "  rango     : " + (
                    if .["cidr0_cidrs"] then
                        (.["cidr0_cidrs"][0] | "\(.v4prefix // .v6prefix)/\(.length)")
                    elif .startAddress then "\(.startAddress) - \(.endAddress)"
                    else "?" end
                )
            ' | tee -a "$INFORME"
        else
            printf '%s\n' "$RDAP" | head -40 | tee -a "$INFORME"
        fi
    fi
fi

# ------------------------------------------------------------- veredicto
salida ""
salida "--- Resultado ---------------------------------------------------"
if [ -n "$IP_A" ] && [ "${RC_CURL:-1}" -eq 0 ]; then
    salida " ALCANZABLE: el sitio ha respondido desde esta conexión."
    salida " Si aún así a ti te falla a ratos, repite esta prueba cada vez que"
    salida " falle: lo que vale es la serie con fecha y hora, no una sola foto."
    VEREDICTO=0
elif [ -z "$IP_A" ]; then
    salida " NO RESUELVE EL NOMBRE: el dominio no se ha podido traducir a dirección."
    salida " Prueba desde otra red (datos móviles, otra casa) para saber si es"
    salida " cosa de tu operador o del dominio."
    VEREDICTO=2
else
    salida " NO ALCANZABLE: el nombre resuelve ($IP_A) pero la conexión no llega."
    salida " Guarda este fichero: es exactamente la prueba que hay que adjuntar."
    VEREDICTO=1
fi

# ------------------------------------------------------- qué hacer ahora
cat <<'TEXTO' | tee -a "$INFORME"

--- Y ahora, los otros dos pasos ---------------------------------
 2 · MEDIR. Instala OONI Probe (libre, sin registro) y lanza la prueba
     desde tu propia red: las mediciones se publican solas en OONI
     Explorer. Una anomalía sola no prueba nada, pero suma.
       App e instrucciones : https://ooni.org/install/
       Mediciones públicas : https://explorer.ooni.org/

 3 · DENUNCIAR (esto deja constancia; no hay caso documentado de una
     reclamación individual que levante uno de estos bloqueos):
       · Tu operador, primero, y pide respuesta por escrito.
       · Oficina de Atención al Usuario de Telecomunicaciones (SETELECO):
         https://usuariosteleco.digital.gob.es/reclamaciones/telefonia-e-internet/tramitacion-electronica
       · AEPD, solo si hubo inspección de comunicaciones o tratamiento
         indebido de datos:
         https://www.aepd.es/
       · CNMC, como coordinador de servicios digitales (DSA):
         https://www.cnmc.es/sectores-que-regulamos/servicios-digitales-dsa/reclamaciones

 Guarda también: capturas con la fecha visible, tu operador y, si puedes,
 la misma prueba desde otra conexión.
TEXTO

salida ""
salida "Informe guardado en: $INFORME"
# Sin códigos ANSI a propósito: la salida se guarda tal cual y se puede pegar en
# un informe o un tique de incidencia sin que aparezcan escapes de color.
printf '\nInforme guardado en: %s\n' "$INFORME"
printf 'Código de salida: %s (0 responde · 1 no responde · 2 no resuelve)\n\n' "$VEREDICTO"
exit "$VEREDICTO"
