#!/usr/bin/env bash
# install.sh — Instalador de Arandu AI self-hosted.
#
# Uso (como lo descarga un cliente):
#   curl -fsSLO https://descargas.arandu-ia.com/install.sh
#   bash install.sh [--version 1.0.0-rc.1] [--dir ./arandu] [--port 8080]
#
# Qué hace:
#   1. Detecta el engine de containers (podman preferido; docker soportado).
#   2. Descarga imagen OCI (tar), compose.yaml y cosign.pub.
#   3. Verifica la firma cosign del artefacto (si cosign está instalado).
#   4. Carga la imagen y genera secretos locales (KEK, password de Postgres).
#   5. Escribe el .env de producción y deja instrucciones de TLS y arranque.
#
# Sistemas soportados: Linux, macOS, Windows (WSL2). Requiere: bash, curl,
# openssl y podman (>=4) o docker (>=24) con su plugin compose.

set -euo pipefail

BASE_URL="${ARANDU_DOWNLOAD_BASE:-https://descargas.arandu-ia.com}"
VERSION="1.0.0-rc.1"
INSTALL_DIR="./arandu"
PORT="8080"

while [ $# -gt 0 ]; do
    case "$1" in
        --version) VERSION="$2"; shift 2 ;;
        --dir)     INSTALL_DIR="$2"; shift 2 ;;
        --port)    PORT="$2"; shift 2 ;;
        -h|--help) grep '^#' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
        *) echo "argumento desconocido: $1 (ver --help)"; exit 2 ;;
    esac
done

say()  { printf '\033[1;36m[arandu]\033[0m %s\n' "$*"; }
fail() { printf '\033[1;31m[arandu] ERROR:\033[0m %s\n' "$*" >&2; exit 1; }

# --- 1. Engine ---------------------------------------------------------------
ENGINE=""; COMPOSE=""
if command -v podman >/dev/null 2>&1; then
    ENGINE="podman"
    if podman compose version >/dev/null 2>&1; then COMPOSE="podman compose";
    elif command -v podman-compose >/dev/null 2>&1; then COMPOSE="podman-compose"; fi
elif command -v docker >/dev/null 2>&1; then
    ENGINE="docker"
    if docker compose version >/dev/null 2>&1; then COMPOSE="docker compose"; fi
fi
[ -n "$ENGINE" ]  || fail "no se encontró podman ni docker. Instalá uno (recomendamos podman: https://podman.io/docs/installation)."
[ -n "$COMPOSE" ] || fail "engine '$ENGINE' sin plugin compose. Instalá 'podman compose' (podman>=4.7) o 'docker compose'."
say "engine: $ENGINE | compose: $COMPOSE"

case "$(uname -m)" in
    arm64|aarch64) ARCH="arm64" ;;
    x86_64|amd64)  ARCH="amd64" ;;
    *) fail "arquitectura no soportada: $(uname -m)" ;;
esac
say "arquitectura: $ARCH"

# --- 2. Descargas ------------------------------------------------------------
TAR="arandu-server-${VERSION}-${ARCH}.oci.tar"
mkdir -p "$INSTALL_DIR/secrets"
cd "$INSTALL_DIR"

for f in "$TAR" "$TAR.sig" compose.yaml cosign.pub checksums.txt; do
    if [ ! -f "$f" ]; then
        say "descargando $f ..."
        curl -fSL --progress-bar -o "$f" "$BASE_URL/$f" || fail "descarga fallida: $BASE_URL/$f"
    fi
done

say "verificando checksum ..."
grep "  $TAR\$" checksums.txt | shasum -a 256 -c - >/dev/null 2>&1 \
    || grep "  $TAR\$" checksums.txt | sha256sum -c - >/dev/null 2>&1 \
    || fail "checksum SHA-256 no coincide para $TAR"
say "checksum OK"

# --- 3. Firma ----------------------------------------------------------------
if command -v cosign >/dev/null 2>&1; then
    say "verificando firma cosign ..."
    cosign verify-blob --key cosign.pub --signature "$TAR.sig" --insecure-ignore-tlog=true "$TAR" \
        || fail "la firma cosign NO verifica. NO instales este artefacto."
    say "firma cosign verificada"
else
    say "AVISO: cosign no está instalado; se omite la verificación de firma."
    say "       Para verificarla: https://docs.sigstore.dev/cosign/system_config/installation/"
fi

# --- 4. Imagen y secretos ----------------------------------------------------
say "cargando imagen en $ENGINE ..."
$ENGINE load -i "$TAR" >/dev/null
IMAGE_REF="localhost/arandu-server:${VERSION}"
$ENGINE image exists "$IMAGE_REF" 2>/dev/null || IMAGE_REF="$($ENGINE load -i "$TAR" 2>/dev/null | sed -n 's/^Loaded image: //p' | head -1)"
say "imagen: $IMAGE_REF"

umask 077
[ -f secrets/kek.key ]           || openssl rand -base64 32 > secrets/kek.key
[ -f secrets/postgres-password ] || openssl rand -hex 24   > secrets/postgres-password
PG_PASS="$(cat secrets/postgres-password)"

# --- 5. Configuración --------------------------------------------------------
if [ ! -f .env ]; then
    printf '\n'
    printf 'URL pública de la instancia (https://...). En producción Arandu EXIGE https\n'
    printf 'detrás de un reverse proxy TLS (ej: Caddy). Enter para https://localhost:%s\n' "$PORT"
    read -r -p "APP_URL [https://localhost:${PORT}]: " APP_URL
    APP_URL="${APP_URL:-https://localhost:${PORT}}"
    read -r -p "Email del owner (admin inicial): " OWNER_EMAIL
    [ -n "$OWNER_EMAIL" ] || fail "el email del owner es obligatorio"

    FPRINT="sha256:$(openssl rand -hex 32)"
    cat > .env <<EOF
ARANDU_IMAGE=${IMAGE_REF}
ARANDU_PORT=${PORT}
ARANDU_ENV=production
ARANDU_BIND_ADDR=0.0.0.0:8080
ARANDU_APP_URL=${APP_URL}
ARANDU_DATABASE_URL=postgres://arandu:${PG_PASS}@postgres:5432/arandu
ARANDU_DATABASE_MIGRATE_ON_BOOT=true
ARANDU_REDIS_URL=redis://redis:6379
ARANDU_QDRANT_URL=http://qdrant:6334
ARANDU_DOCUMENT_STORAGE_PATH=/var/lib/arandu/storage
ARANDU_MASTER_KEY_FILE=/run/secrets/kek
ARANDU_KEY_VERSION=1
ARANDU_ENABLE_RAG=true
ARANDU_OWNER_EMAIL=${OWNER_EMAIL}
ARANDU_LICENSE_MODE=remote
ARANDU_LICENSE_SERVER_URL=https://license.arandu-ia.com
ARANDU_LICENSE_STATE_FILE=/var/lib/arandu/storage/license-state.json
ARANDU_LICENSE_INSTANCE_ID=ins_$(openssl rand -hex 6)
ARANDU_LICENSE_INSTANCE_FINGERPRINT=${FPRINT}
ARANDU_LOG_LEVEL=info
ARANDU_LOG_FORMAT=json
ARANDU_MAX_REQUEST_BYTES=26214400
EOF
    chmod 600 .env
    say ".env de producción generado"
else
    say ".env existente conservado"
fi

# --- 6. Próximos pasos -------------------------------------------------------
cat <<EOF

================================================================
 Instalación preparada en: $(pwd)

 1) TLS OBLIGATORIO en producción. Ejemplo con Caddy (caddyserver.com):

      <tu-dominio-o-localhost> {
          reverse_proxy 127.0.0.1:${PORT}
      }

    (Caddy emite/renueva el certificado solo; para localhost usa su CA local)

 2) Arrancar el stack:
      ${COMPOSE} --env-file .env up -d

 3) Primer login: el bootstrap del owner imprime una password efímera
    en los logs del primer arranque:
      ${ENGINE} logs \$(${ENGINE} ps --format '{{.Names}}' | grep arandu-server) | grep owner_bootstrap

 4) Abrir la consola en la APP_URL configurada, completar el wizard.
    La instancia activa sola su trial de 30 días contra
    license.arandu-ia.com (necesita salida HTTPS a internet).

 Documentación completa: https://arandu-ia.com/descargas
================================================================
EOF
say "listo."
