#!/bin/bash
# =============================================================================
# Lilith Platform - Complete Development Environment Installer
# =============================================================================
#
# One-command setup for the entire development environment.
# Run this once on a new machine to get everything ready.
#
# Usage:
#   ./install              # Full installation
#   ./install --check      # Check what's installed
#   ./install dr <args>    # Disaster Recovery CLI (legacy)
#   ./install --help       # Show help
#
# What this does:
#   1. Checks prerequisites (Docker, pnpm, etc.)
#   2. Creates bigdisk storage directories
#   3. Configures .local domain DNS (requires sudo)
#   4. Installs pnpm dependencies
#   5. Builds Docker images
#   6. Prints next steps
#

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"

# Legacy: Forward 'dr' subcommand to disaster recovery installer
if [[ "${1:-}" == "dr" || "${1:-}" == "plum" ]]; then
    exec "$SCRIPT_DIR/infrastructure/provisioning/install-dr-cli.sh" "$@"
fi

# =============================================================================
# Configuration
# =============================================================================

BIGDISK_DEV="/mnt/bigdisk/_/@lilith/dev/lilith-platform"
REQUIRED_DIRS=(postgres redis meilisearch minio seeds sdxl-models image-gen-jobs)

DOMAINS=(
    "atlilith.local"
    "trustedmeet.local"
)

# =============================================================================
# Colors & Logging
# =============================================================================

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

log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[OK]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
log_step() { echo -e "\n${CYAN}${BOLD}▸ $1${NC}"; }

# =============================================================================
# Sudo Helper
# =============================================================================

SUDO_KEEPALIVE_PID=""

ensure_sudo() {
    if [[ $EUID -eq 0 ]]; then
        return 0
    fi

    echo ""
    log_info "Some steps require sudo access. You may be prompted for your password."
    echo ""

    if ! sudo -v; then
        log_error "Failed to obtain sudo access"
        exit 1
    fi

    # Keep sudo alive in background
    (while true; do sudo -n true; sleep 50; done) 2>/dev/null &
    SUDO_KEEPALIVE_PID=$!
}

cleanup() {
    if [[ -n "$SUDO_KEEPALIVE_PID" ]]; then
        kill "$SUDO_KEEPALIVE_PID" 2>/dev/null || true
    fi
}
trap cleanup EXIT

# =============================================================================
# Prerequisites Check
# =============================================================================

check_prerequisites() {
    log_step "Checking prerequisites"

    local missing=()

    # Docker
    if command -v docker &>/dev/null; then
        local docker_version
        docker_version=$(docker --version | grep -oP '\d+\.\d+' | head -1)
        log_success "Docker ${docker_version}"
    else
        missing+=("docker")
        log_error "Docker not found"
    fi

    # Docker Compose (v2)
    if docker compose version &>/dev/null; then
        local compose_version
        compose_version=$(docker compose version --short 2>/dev/null || echo "unknown")
        log_success "Docker Compose ${compose_version}"
    else
        missing+=("docker-compose-v2")
        log_error "Docker Compose v2 not found"
    fi

    # Node.js
    if command -v node &>/dev/null; then
        local node_version
        node_version=$(node --version)
        log_success "Node.js ${node_version}"
    else
        missing+=("node")
        log_error "Node.js not found"
    fi

    # pnpm
    if command -v pnpm &>/dev/null; then
        local pnpm_version
        pnpm_version=$(pnpm --version)
        log_success "pnpm ${pnpm_version}"
    else
        missing+=("pnpm")
        log_error "pnpm not found"
    fi

    # Git
    if command -v git &>/dev/null; then
        log_success "Git $(git --version | cut -d' ' -f3)"
    else
        missing+=("git")
        log_error "Git not found"
    fi

    # curl
    if command -v curl &>/dev/null; then
        log_success "curl"
    else
        missing+=("curl")
        log_error "curl not found"
    fi

    # Check Docker daemon
    if docker info &>/dev/null; then
        log_success "Docker daemon running"
    else
        log_error "Docker daemon not running"
        missing+=("docker-daemon")
    fi

    # Check bigdisk mount
    if [[ -d "/mnt/bigdisk" ]]; then
        log_success "bigdisk mounted at /mnt/bigdisk"
    else
        log_warn "bigdisk not mounted at /mnt/bigdisk (optional for data persistence)"
    fi

    # Check NVIDIA (optional)
    if command -v nvidia-smi &>/dev/null; then
        local gpu_info
        gpu_info=$(nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null | head -1)
        log_success "NVIDIA GPU: ${gpu_info}"

        if docker run --rm --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi &>/dev/null; then
            log_success "NVIDIA Container Toolkit working"
        else
            log_warn "NVIDIA Container Toolkit not configured (GPU services unavailable)"
        fi
    else
        log_info "No NVIDIA GPU detected (GPU services unavailable)"
    fi

    if [[ ${#missing[@]} -gt 0 ]]; then
        echo ""
        log_error "Missing prerequisites: ${missing[*]}"
        echo ""
        echo "Install missing dependencies:"
        echo "  Docker:   https://docs.docker.com/engine/install/"
        echo "  Node.js:  https://nodejs.org/ or 'dnf install nodejs'"
        echo "  pnpm:     'corepack enable pnpm' or 'npm install -g pnpm'"
        echo ""
        exit 1
    fi

    log_success "All prerequisites satisfied"
}

# =============================================================================
# bigdisk Storage Setup
# =============================================================================

setup_bigdisk() {
    log_step "Setting up bigdisk storage"

    if [[ ! -d "/mnt/bigdisk" ]]; then
        log_warn "bigdisk not available - using Docker volumes instead"
        log_info "Data will be stored in Docker volumes (less persistent)"
        return 0
    fi

    # Create base directory
    if [[ ! -d "$BIGDISK_DEV" ]]; then
        log_info "Creating ${BIGDISK_DEV}..."
        mkdir -p "$BIGDISK_DEV"
    fi

    # Create data directories
    for dir in "${REQUIRED_DIRS[@]}"; do
        local full_path="${BIGDISK_DEV}/${dir}"
        if [[ ! -d "$full_path" ]]; then
            mkdir -p "$full_path"
            log_info "Created ${dir}/"
        fi
    done

    # Set permissions
    chmod -R 775 "$BIGDISK_DEV"

    log_success "bigdisk storage ready at ${BIGDISK_DEV}"
}

# =============================================================================
# DNS Configuration
# =============================================================================

setup_dns() {
    log_step "Configuring .local domain DNS"

    # Check if domains already resolve
    local all_resolved=true
    for domain in "${DOMAINS[@]}"; do
        local result
        result=$(getent hosts "www.${domain}" 2>/dev/null | awk '{print $1}') || true
        if [[ "$result" != "127.0.0.1" ]]; then
            all_resolved=false
            break
        fi
    done

    if $all_resolved; then
        log_success "DNS already configured - all domains resolve to 127.0.0.1"
        return 0
    fi

    log_info "DNS configuration requires sudo access"

    # Check for dnsmasq
    if ! command -v dnsmasq &>/dev/null; then
        log_info "Installing dnsmasq..."
        if command -v dnf &>/dev/null; then
            sudo dnf install -y dnsmasq
        elif command -v apt &>/dev/null; then
            sudo apt update && sudo apt install -y dnsmasq
        elif command -v pacman &>/dev/null; then
            sudo pacman -S --noconfirm dnsmasq
        else
            log_error "Cannot install dnsmasq - please install manually"
            exit 1
        fi
    fi

    # Create dnsmasq config
    local dnsmasq_conf="/etc/dnsmasq.d/lilith-local.conf"
    log_info "Creating ${dnsmasq_conf}..."

    sudo tee "$dnsmasq_conf" > /dev/null << 'EOF'
# Lilith Platform - Local Development DNS
# Resolves .local domains to localhost

# atlilith.local wildcard
address=/.atlilith.local/127.0.0.1

# trustedmeet.local wildcard
address=/.trustedmeet.local/127.0.0.1
EOF

    # Ensure dnsmasq reads conf.d
    if [[ -f /etc/dnsmasq.conf ]]; then
        if ! grep -q "^conf-dir=/etc/dnsmasq.d" /etc/dnsmasq.conf; then
            echo "conf-dir=/etc/dnsmasq.d" | sudo tee -a /etc/dnsmasq.conf > /dev/null
        fi
    fi

    # Configure systemd-resolved if present
    if systemctl is-active --quiet systemd-resolved; then
        log_info "Configuring systemd-resolved integration..."

        sudo mkdir -p /etc/systemd/resolved.conf.d
        sudo tee /etc/systemd/resolved.conf.d/dnsmasq.conf > /dev/null << 'EOF'
[Resolve]
DNS=127.0.0.1
Domains=~atlilith.local ~trustedmeet.local
EOF
        sudo systemctl restart systemd-resolved
    fi

    # Start/restart dnsmasq
    log_info "Starting dnsmasq..."
    sudo systemctl enable dnsmasq
    sudo systemctl restart dnsmasq

    # Verify
    sleep 1
    local test_result
    test_result=$(getent hosts www.atlilith.local 2>/dev/null | awk '{print $1}') || true

    if [[ "$test_result" == "127.0.0.1" ]]; then
        log_success "DNS configured - www.atlilith.local → 127.0.0.1"
    else
        log_warn "DNS verification failed - you may need to restart your network"
        log_info "Try: sudo systemctl restart NetworkManager"
    fi
}

# =============================================================================
# Dependencies Installation
# =============================================================================

install_dependencies() {
    log_step "Installing pnpm dependencies"

    if [[ -f "codebase/package.json" ]]; then
        log_info "Running pnpm install in codebase/..."
        (cd codebase && pnpm install)
        log_success "Dependencies installed"
    else
        log_warn "No codebase/package.json found - skipping pnpm install"
    fi
}

# =============================================================================
# Docker Images
# =============================================================================

build_docker_images() {
    log_step "Building Docker images"

    local compose_file="infrastructure/docker/docker-compose.dev-all.yml"

    if [[ ! -f "$compose_file" ]]; then
        log_error "Compose file not found: ${compose_file}"
        exit 1
    fi

    log_info "Pulling base images..."
    docker compose -f "$compose_file" pull --ignore-pull-failures 2>/dev/null || true

    log_info "Building custom images (this may take a while)..."
    docker compose -f "$compose_file" build --parallel 2>/dev/null || true

    log_success "Docker images ready"
}

# =============================================================================
# Check Installation
# =============================================================================

check_installation() {
    echo ""
    echo -e "${BOLD}${CYAN}═══════════════════════════════════════════════════════════════${NC}"
    echo -e "${BOLD}  Lilith Platform Installation Status${NC}"
    echo -e "${BOLD}${CYAN}═══════════════════════════════════════════════════════════════${NC}"
    echo ""

    # Prerequisites
    echo -e "${BOLD}Prerequisites:${NC}"
    for cmd in docker node pnpm git curl; do
        if command -v $cmd &>/dev/null; then
            echo -e "  ${GREEN}✓${NC} ${cmd}"
        else
            echo -e "  ${RED}✗${NC} ${cmd}"
        fi
    done

    # Docker
    echo ""
    echo -e "${BOLD}Docker:${NC}"
    if docker info &>/dev/null; then
        echo -e "  ${GREEN}✓${NC} Docker daemon running"
    else
        echo -e "  ${RED}✗${NC} Docker daemon not running"
    fi

    if docker compose version &>/dev/null; then
        echo -e "  ${GREEN}✓${NC} Docker Compose v2"
    else
        echo -e "  ${RED}✗${NC} Docker Compose v2"
    fi

    # bigdisk
    echo ""
    echo -e "${BOLD}Storage:${NC}"
    if [[ -d "$BIGDISK_DEV" ]]; then
        echo -e "  ${GREEN}✓${NC} bigdisk storage at ${BIGDISK_DEV}"
    else
        echo -e "  ${YELLOW}○${NC} bigdisk not configured (using Docker volumes)"
    fi

    # DNS
    echo ""
    echo -e "${BOLD}DNS Resolution:${NC}"
    for domain in www.atlilith.local admin.atlilith.local www.trustedmeet.local; do
        local result
        result=$(getent hosts "$domain" 2>/dev/null | awk '{print $1}') || true
        if [[ "$result" == "127.0.0.1" ]]; then
            echo -e "  ${GREEN}✓${NC} ${domain}"
        else
            echo -e "  ${RED}✗${NC} ${domain}"
        fi
    done

    # GPU
    echo ""
    echo -e "${BOLD}GPU (optional):${NC}"
    if command -v nvidia-smi &>/dev/null; then
        echo -e "  ${GREEN}✓${NC} NVIDIA driver installed"
        if docker run --rm --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 echo "ok" &>/dev/null; then
            echo -e "  ${GREEN}✓${NC} NVIDIA Container Toolkit"
        else
            echo -e "  ${YELLOW}○${NC} NVIDIA Container Toolkit not working"
        fi
    else
        echo -e "  ${DIM}○ No NVIDIA GPU${NC}"
    fi

    echo ""
    echo -e "${BOLD}${CYAN}═══════════════════════════════════════════════════════════════${NC}"
    echo ""
}

# =============================================================================
# Print Next Steps
# =============================================================================

print_next_steps() {
    echo ""
    echo -e "${BOLD}${MAGENTA}╔══════════════════════════════════════════════════════════════════════════════╗${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}  ${BOLD}🌸 Installation Complete!${NC}                                                   ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}╠══════════════════════════════════════════════════════════════════════════════╣${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}                                                                              ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}  ${CYAN}Start the development environment:${NC}                                        ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}                                                                              ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}    ${BOLD}./run dev${NC}                    Start everything                            ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}    ${BOLD}./run dev --gpu${NC}              Include GPU services (@imajin)              ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}    ${BOLD}./run dev --debug${NC}            Include debug tools (pgAdmin, Redis UI)     ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}                                                                              ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}  ${CYAN}URLs (after starting):${NC}                                                    ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}                                                                              ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}    http://www.atlilith.local          Landing page                           ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}    http://admin.atlilith.local        Platform admin                         ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}    http://api.atlilith.local          Platform API                           ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}    http://www.trustedmeet.local       Marketplace                            ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}                                                                              ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}  ${CYAN}Other commands:${NC}                                                           ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}                                                                              ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}    ${BOLD}./run dev stop${NC}               Stop all services                          ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}    ${BOLD}./run dev status${NC}             Show service status                        ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}║${NC}                                                                              ${BOLD}${MAGENTA}║${NC}"
    echo -e "${BOLD}${MAGENTA}╚══════════════════════════════════════════════════════════════════════════════╝${NC}"
    echo ""
}

# =============================================================================
# Help
# =============================================================================

show_help() {
    cat << 'EOF'
Lilith Platform - Development Environment Installer

Usage: ./install [OPTIONS]

Options:
  --check       Check installation status without making changes
  --skip-deps   Skip pnpm install
  --skip-dns    Skip DNS configuration
  --help        Show this help

Subcommands:
  dr <args>     Disaster Recovery CLI installer (legacy)
  plum <args>   Alias for 'dr' (legacy)

What this installer does:
  1. Checks prerequisites (Docker, Node.js, pnpm, etc.)
  2. Creates bigdisk storage directories (if bigdisk mounted)
  3. Configures dnsmasq for .local domain resolution
  4. Installs pnpm dependencies
  5. Pre-builds Docker images

After installation, run:
  ./run dev              Start everything
  ./run dev --gpu        Start with GPU services

EOF
}

# =============================================================================
# Main
# =============================================================================

main() {
    local skip_deps=false
    local skip_dns=false
    local check_only=false

    while [[ $# -gt 0 ]]; do
        case "$1" in
            --check)
                check_only=true
                shift
                ;;
            --skip-deps)
                skip_deps=true
                shift
                ;;
            --skip-dns)
                skip_dns=true
                shift
                ;;
            --help|-h)
                show_help
                exit 0
                ;;
            *)
                log_error "Unknown option: $1"
                show_help
                exit 1
                ;;
        esac
    done

    if $check_only; then
        check_installation
        exit 0
    fi

    echo ""
    echo -e "${BOLD}${MAGENTA}🌸 Lilith Platform Installer${NC}"
    echo ""

    # Check prerequisites first (no sudo needed)
    check_prerequisites

    # Get sudo early if we need DNS setup
    if ! $skip_dns; then
        ensure_sudo
    fi

    # Setup bigdisk storage
    setup_bigdisk

    # Configure DNS
    if ! $skip_dns; then
        setup_dns
    fi

    # Install dependencies
    if ! $skip_deps; then
        install_dependencies
    fi

    # Build Docker images
    build_docker_images

    # Done!
    print_next_steps
}

main "$@"
