#!/usr/bin/env bash
#
# Comprueba que el portal este bien montado en Virtualmin.
#
#   sudo bash verificar-portal.sh reportes.incide.com.co incide
#
# Se puede correr las veces que quieras: no cambia nada, solo informa. Es la
# forma rapida de saber si el problema es de configuracion o de otro lado.
#
# Devuelve codigo 0 si todo esta bien, 1 si hay problemas.

set -uo pipefail

DOMINIO="${1:-reportes.incide.com.co}"
USUARIO="${2:-incide}"
CARPETA="/home/$USUARIO"

PROBLEMAS=0

ok()    { printf '  \033[32mOK\033[0m  %s\n' "$1"; }
aviso() { printf '  \033[33m!!\033[0m  %s\n' "$1"; }
mal()   { printf '  \033[31mXX\033[0m  %s\n' "$1"; PROBLEMAS=$((PROBLEMAS + 1)); }

printf '\n\033[1;36m  Comprobacion del portal en Virtualmin\033[0m\n'
printf '  %s\n\n' "----------------------------------------"

# ---------------------------------------------------------------------------
printf '\033[1m1. DNS y conectividad\033[0m\n'

IP_SERVIDOR=$(curl -s --max-time 8 https://api.ipify.org 2>/dev/null || echo "")
IP_DOMINIO=$(getent hosts "$DOMINIO" 2>/dev/null | awk '{print $1}' | head -1)

if [[ -z "$IP_DOMINIO" ]]; then
    mal "$DOMINIO no resuelve. Crea el registro DNS A que apunte a este servidor."
elif [[ -z "$IP_SERVIDOR" ]]; then
    aviso "No se pudo determinar la IP publica (sin salida a internet?)"
elif [[ "$IP_DOMINIO" == "$IP_SERVIDOR" ]]; then
    ok "$DOMINIO -> $IP_DOMINIO (este servidor)"
else
    mal "$DOMINIO -> $IP_DOMINIO, pero este servidor es $IP_SERVIDOR"
fi

# ---------------------------------------------------------------------------
printf '\n\033[1m2. El limite que se olvida: nginx\033[0m\n'

CONF_NGINX="/etc/nginx/conf.d/$DOMINIO.conf"
TIMEOUT_ACTUAL=$(nginx -T 2>/dev/null | grep -A400 "server_name $DOMINIO" \
                | grep -m1 'fastcgi_read_timeout' | grep -oE '[0-9]+s?')

if [[ -z "$TIMEOUT_ACTUAL" ]]; then
    mal "No hay fastcgi_read_timeout para $DOMINIO. Sin esto, los reportes de mas de 60 s fallan."
    mal "  Anade dentro del bloque server en $CONF_NGINX:"
    mal "      fastcgi_read_timeout 300s;"
elif [[ "${TIMEOUT_ACTUAL%%s}" -lt 120 ]]; then
    mal "fastcgi_read_timeout = $TIMEOUT_ACTUAL. Necesita 300s."
    mal "  Los reportes en frio tardan ~70 s en armarse."
else
    ok "fastcgi_read_timeout = $TIMEOUT_ACTUAL"
fi

if nginx -T 2>/dev/null | grep -A400 "server_name $DOMINIO" | grep -q 'fastcgi_param[[:space:]]*HTTPS'; then
    ok "el esquema HTTPS se pasa a PHP"
else
    mal "Falta fastcgi_param HTTPS. Laravel creera que la peticion es http"
    mal "  y las URLs del portal saldran sin cifrar."
fi

# ---------------------------------------------------------------------------
printf '\n\033[1m3. Limites de PHP\033[0m\n'

if ! command -v virtualmin >/dev/null; then
    mal "Virtualmin no esta instalado."
else
    INIS=$(virtualmin list-domains --domain "$DOMINIO" --name-only 2>/dev/null)
    if [[ -z "$INIS" ]]; then
        mal "El dominio $DOMINIO no existe en Virtualmin."
    else
        ok "el dominio existe"

        for par in "max_execution_time:300" "memory_limit:512M"; do
            nombre="${par%%:*}"; necesario="${par##*:}"
            actual=$(virtualmin modify-php-ini --domain "$DOMINIO" \
                     --show-all 2>/dev/null | grep -i "^$nombre" | head -1 | awk '{print $NF}')
            [[ -z "$actual" ]] && actual=$(php -r "echo ini_get('$nombre');" 2>/dev/null)

            if [[ -z "$actual" ]]; then
                mal "$nombre no se pudo leer"
            elif [[ "$nombre" == "max_execution_time" && "${actual%%s}" != "0" && "${actual%%s}" -lt 120 ]]; then
                mal "$nombre = $actual, necesita 300 (o 0 = sin limite)"
            elif [[ "$nombre" == "memory_limit" && "${actual%M}" -lt 256 ]]; then
                mal "$nombre = $actual, necesita 512M"
            else
                ok "$(printf '%-20s %s' "$nombre" "$actual")"
            fi
        done
    fi
fi

# ---------------------------------------------------------------------------
printf '\n\033[1m4. Raiz del documento y proteccion\033[0m\n'

if [[ ! -d "$CARPETA" ]]; then
    mal "No existe $CARPETA. El codigo no esta subido."
else
    ok "el codigo esta en $CARPETA"

    for carpeta in storage/app/Admision storage/app/sihos-cache \
                  storage/framework/views storage/framework/sessions \
                  storage/logs bootstrap/cache database/sqlite; do
        if [[ -d "$CARPETA/$carpeta" ]]; then
            if [[ -w "$CARPETA/$carpeta" ]]; then
                ok "$(printf '%-38s escribible' "$carpeta")"
            else
                mal "$carpeta no tiene permiso de escritura"
                mal "  chown -R $USUARIO:$USUARIO $CARPETA/$carpeta && chmod 775 $CARPETA/$carpeta"
            fi
        else
            mal "falta $carpeta"
        fi
    done

    if [[ -f "$CARPETA/.env" ]]; then
        if grep -qE '^APP_DEBUG=(true|1)$' "$CARPETA/.env"; then
            mal "APP_DEBUG=true en produccion: se muestran pantallas con datos internos."
        else
            ok "APP_DEBUG en false"
        fi
        if grep -qE '^SQLITE_DATABASE=[A-Za-z]:' "$CARPETA/.env"; then
            mal "SQLITE_DATABASE apunta a una ruta de Windows. En Linux no existe."
        else
            ok "SQLITE_DATABASE con ruta relativa"
        fi
        if grep -qE '^APP_KEY=.+$' "$CARPETA/.env"; then
            ok "APP_KEY puesta"
        else
            mal "APP_KEY vacia. php artisan key:generate --show"
        fi
    else
        mal "No existe $CARPETA/.env. Copia .env.example y pon las credenciales."
    fi

    if [[ -d "$CARPETA/vendor" ]]; then
        ok "dependencias instaladas"
    else
        mal "Falta vendor/. Corre: composer install --no-dev"
    fi

    # El .htaccess no sirve con nginx, pero si el sitio llega a moverse a
    # Apache evita exponer los PDF clinicos.
    for archivo in storage/.htaccess database/.htaccess; do
        [[ -f "$CARPETA/$archivo" ]] && ok "$archivo presente" \
            || aviso "$archivo ausente (importa solo si algun dia usan Apache)"
    done
fi

# ---------------------------------------------------------------------------
printf '\n\033[1m5. SSL\033[0m\n'

if [[ -f "$CARPETA/ssl.combined" || -f "$CARPETA/ssl.cert" ]]; then
    ok "hay certificado"
    if [[ -f "$CARPETA/ssl.cert" ]]; then
        ok "expira: $(openssl x509 -enddate -noout -in "$CARPETA/ssl.cert" 2>/dev/null | cut -d= -f2)"
    fi
else
    mal "sin certificado. Panel -> SSL Certificate -> Request -> Let's Encrypt"
fi

if [[ -f "$CARPETA/public/test.html" ]]; then
    aviso "public/test.html sigue publicada y no tiene contraseña."
fi

# ---------------------------------------------------------------------------
printf '\n\033[1m6. La prueba que importa: generar un PDF\033[0m\n'

if [[ -f "$CARPETA/artisan" && -f "$CARPETA/.env" ]]; then
    SALIDA=$(su - "$USUARIO" -c "cd $CARPETA && php artisan instalacion:verificar" 2>&1)
    echo "$SALIDA" | sed 's/^/  /' | tail -25

    if echo "$SALIDA" | grep -q 'Todo correcto'; then
        ok "el portal esta operativo"
    else
        mal "instalacion:verificar reporta problemas (arriba el detalle)"
    fi
else
    aviso "Faltan el .env o el codigo: no se puede probar la generacion de PDF"
fi

# ---------------------------------------------------------------------------
printf '\n  %s\n' "----------------------------------------"
if [[ $PROBLEMAS -eq 0 ]]; then
    printf '\n\033[1;32m  Todo en orden\033[0m\n\n'
    exit 0
else
    printf '\n\033[1;31m  %d problema(s) por resolver\033[0m\n\n' "$PROBLEMAS"
    exit 1
fi