#!/usr/bin/env bash
# =================================================================
# LLMHosts.com — Server Bootstrap Script
# =================================================================
# Sets up a fresh Ubuntu server with LLMHosts in < 10 minutes.
#
# Usage:
#   curl -fsSL https://raw.githubusercontent.com/LookNoHandsMom/LLMHosts.com/main/scripts/bootstrap.sh | bash
#
# Or after cloning:
#   chmod +x scripts/bootstrap.sh && ./scripts/bootstrap.sh
#
# Options (environment variables):
#   DOMAIN          — Your domain (default: localhost)
#   ACME_EMAIL      — Let's Encrypt email (default: admin@$DOMAIN)
#   DEPLOY_MODE     — "standalone" or "external-proxy" (default: standalone)
#   SKIP_FIREWALL   — Set to 1 to skip UFW setup (default: 0)
#   SKIP_GPU        — Set to 1 to skip GPU detection (default: 0)
#
# Requirements:
#   - Ubuntu 22.04+ or Debian 12+
#   - Root or sudo access
#   - Internet connection
# =================================================================
set -euo pipefail

# --- Colors ---
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

log()   { echo -e "${GREEN}[✓]${NC} $*"; }
warn()  { echo -e "${YELLOW}[!]${NC} $*"; }
error() { echo -e "${RED}[✗]${NC} $*" >&2; }
info()  { echo -e "${BLUE}[i]${NC} $*"; }

# --- Configuration ---
DOMAIN="${DOMAIN:-localhost}"
ACME_EMAIL="${ACME_EMAIL:-admin@${DOMAIN}}"
DEPLOY_MODE="${DEPLOY_MODE:-standalone}"
SKIP_FIREWALL="${SKIP_FIREWALL:-0}"
SKIP_GPU="${SKIP_GPU:-0}"
REPO_URL="https://github.com/LookNoHandsMom/LLMHosts.com.git"
INSTALL_DIR="${INSTALL_DIR:-$(pwd)/LLMHosts.com}"

echo ""
echo "=============================================="
echo "  LLMHosts.com — Server Bootstrap"
echo "=============================================="
echo ""
info "Domain:       $DOMAIN"
info "Deploy mode:  $DEPLOY_MODE"
info "Install dir:  $INSTALL_DIR"
echo ""

# --- Pre-flight checks ---
if [[ $EUID -eq 0 ]]; then
    warn "Running as root. Consider creating a non-root user first."
    warn "See: docs/deployment/vps-guide.md"
fi

if ! command -v apt-get &>/dev/null; then
    error "This script requires apt-get (Ubuntu/Debian). Exiting."
    exit 1
fi

# --- Step 1: System packages ---
log "Updating system packages..."
sudo apt-get update -qq
sudo apt-get install -y -qq git curl wget ca-certificates gnupg lsb-release > /dev/null

# --- Step 2: Install Docker ---
if command -v docker &>/dev/null; then
    log "Docker already installed: $(docker --version)"
else
    log "Installing Docker..."
    curl -fsSL https://get.docker.com | sh
    # Add current user to docker group if not root
    if [[ $EUID -ne 0 ]]; then
        sudo usermod -aG docker "$USER"
        warn "Added $USER to docker group. You may need to log out and back in."
    fi
    log "Docker installed: $(docker --version)"
fi

# Verify docker compose plugin
if ! docker compose version &>/dev/null; then
    error "Docker Compose plugin not found. Install Docker Compose v2."
    exit 1
fi
log "Docker Compose: $(docker compose version --short)"

# --- Step 3: GPU detection ---
GPU_DETECTED=false
if [[ "$SKIP_GPU" != "1" ]] && command -v nvidia-smi &>/dev/null; then
    GPU_DETECTED=true
    log "NVIDIA GPU detected: $(nvidia-smi --query-gpu=name --format=csv,noheader | head -1)"

    if ! dpkg -l | grep -q nvidia-container-toolkit; then
        log "Installing nvidia-container-toolkit..."
        curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \
            sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg 2>/dev/null
        curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
            sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
            sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list > /dev/null
        sudo apt-get update -qq
        sudo apt-get install -y -qq nvidia-container-toolkit > /dev/null
        sudo nvidia-ctk runtime configure --runtime=docker > /dev/null 2>&1
        sudo systemctl restart docker
        log "nvidia-container-toolkit installed"
    else
        log "nvidia-container-toolkit already installed"
    fi
else
    info "No NVIDIA GPU detected (or SKIP_GPU=1). Running in CPU-only mode."
fi

# --- Step 4: Firewall ---
if [[ "$SKIP_FIREWALL" != "1" ]]; then
    if command -v ufw &>/dev/null; then
        log "Configuring firewall (UFW)..."
        sudo ufw default deny incoming > /dev/null 2>&1 || true
        sudo ufw default allow outgoing > /dev/null 2>&1 || true
        sudo ufw allow 22/tcp > /dev/null 2>&1 || true
        sudo ufw allow 80/tcp > /dev/null 2>&1 || true
        sudo ufw allow 443/tcp > /dev/null 2>&1 || true
        echo "y" | sudo ufw enable > /dev/null 2>&1 || true
        log "Firewall configured: SSH(22), HTTP(80), HTTPS(443)"
    else
        warn "UFW not found. Skipping firewall setup."
    fi
else
    info "Skipping firewall setup (SKIP_FIREWALL=1)"
fi

# --- Step 5: Clone or update repo ---
if [[ -d "$INSTALL_DIR/.git" ]]; then
    log "Repository exists. Pulling latest..."
    git -C "$INSTALL_DIR" pull origin main --quiet
else
    log "Cloning LLMHosts.com..."
    git clone --quiet "$REPO_URL" "$INSTALL_DIR"
fi
cd "$INSTALL_DIR"

# --- Step 6: Create .env ---
if [[ ! -f .env ]]; then
    log "Creating .env from template..."
    cat > .env << EOF
# Generated by bootstrap.sh on $(date -u +"%Y-%m-%dT%H:%M:%SZ")
DOMAIN=${DOMAIN}
ACME_EMAIL=${ACME_EMAIL}

# Application
LLMHOST_SERVER_HOST=0.0.0.0
LLMHOST_SECURITY_REQUIREAUTH=true
LLMHOST_SERVER_LOGLEVEL=info
LLMHOST_OBSERVABILITY_LOGFORMAT=json

# Cache
LLMHOST_CACHE_ENABLED=true
LLMHOST_CACHE_MAXSIZEMB=1024

# Auth (generate a real secret for production)
NEXTAUTH_SECRET=$(openssl rand -base64 32)

# Uncomment and fill in as needed:
# STRIPE_SECRET_KEY=sk_live_...
# RESEND_API_KEY=re_...
# LLMHOST_OLLAMA_HOST=http://host.docker.internal:11434
EOF
    log ".env created with generated NEXTAUTH_SECRET"
else
    log ".env already exists. Skipping."
fi

# --- Step 7: Create frontend .env ---
if [[ ! -f frontend/.env ]]; then
    NEXTAUTH_SECRET_VAL=$(grep NEXTAUTH_SECRET .env | cut -d= -f2-)
    cat > frontend/.env << EOF
DATABASE_URL="file:/data/llmhost.db"
NEXTAUTH_URL="https://${DOMAIN}"
NEXTAUTH_SECRET="${NEXTAUTH_SECRET_VAL}"
AUTH_TRUST_HOST=true
NEXT_PUBLIC_APP_URL="https://${DOMAIN}"
NEXT_PUBLIC_API_URL="https://${DOMAIN}"
EOF
    log "frontend/.env created"
fi

# --- Step 8: Build and start ---
log "Building Docker images (this may take a few minutes)..."

COMPOSE_FILES="-f docker-compose.prod.yml"
if [[ "$DEPLOY_MODE" == "external-proxy" ]]; then
    COMPOSE_FILES="$COMPOSE_FILES -f docker-compose.external-proxy.yml"
    info "Using external proxy mode"
fi

docker compose $COMPOSE_FILES build --quiet 2>&1 | tail -5

log "Starting services..."
docker compose $COMPOSE_FILES up -d

# --- Step 9: Wait for health ---
log "Waiting for services to start..."
RETRIES=0
MAX_RETRIES=30
while [[ $RETRIES -lt $MAX_RETRIES ]]; do
    if docker compose $COMPOSE_FILES exec -T llmhost python3 -c "import httpx; httpx.get('http://localhost:4000/health').raise_for_status()" 2>/dev/null; then
        break
    fi
    RETRIES=$((RETRIES + 1))
    sleep 2
done

if [[ $RETRIES -ge $MAX_RETRIES ]]; then
    warn "Health check timed out. Check logs: docker compose $COMPOSE_FILES logs llmhost"
else
    log "LLMHosts is healthy!"
fi

# --- Summary ---
echo ""
echo "=============================================="
echo "  Bootstrap Complete"
echo "=============================================="
echo ""
log "LLMHosts is running at:"
if [[ "$DOMAIN" != "localhost" ]]; then
    info "  https://${DOMAIN}/health"
    info "  https://${DOMAIN}/v1/models"
else
    info "  http://localhost:4000/health"
    info "  http://localhost:4000/v1/models"
fi
echo ""
if [[ "$GPU_DETECTED" == "true" ]]; then
    log "GPU: Detected and configured"
else
    info "GPU: Not detected (CPU-only mode)"
fi
echo ""
info "Next steps:"
info "  1. Add API keys:  docker compose $COMPOSE_FILES exec llmhost llmhost keys add openai sk-..."
info "  2. Verify:        docker compose $COMPOSE_FILES exec llmhost llmhost doctor"
info "  3. View logs:     docker compose $COMPOSE_FILES logs -f"
if [[ "$DOMAIN" == "localhost" ]]; then
    info "  4. Set DOMAIN in .env for TLS:  DOMAIN=your.domain.com"
fi
echo ""
