#!/usr/bin/env bash

# Setup script for Besu node on VM
# This script installs Docker, configures the node, and starts Besu

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../lib/init.sh"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"

# Configuration
NODE_TYPE="${1:-validator}"
NODE_INDEX="${2:-0}"
CLUSTER_NAME="${CLUSTER_NAME:-defi-oracle-aks}"
KEY_VAULT_NAME="${KEY_VAULT_NAME:-defi-oracle-kv}"
GENESIS_FILE_PATH="${GENESIS_FILE_PATH:-/opt/besu/config/genesis.json}"


log_success "Setting up Besu node: $NODE_TYPE-$NODE_INDEX"

# Check if running as root
if [ "$EUID" -ne 0 ]; then
    log_error "Please run as root or with sudo"
    exit 1
fi

# Update system
log_warn "Updating system..."
apt-get update
apt-get upgrade -y

# Install dependencies
log_warn "Installing dependencies..."
apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release \
    jq \
    wget \
    unzip \
    software-properties-common

# Install Docker
if ! command -v docker &> /dev/null; then
    log_warn "Installing Docker..."
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
    apt-get update
    apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
    systemctl enable docker
    systemctl start docker
    usermod -aG docker $SUDO_USER
    log_success "✓ Docker installed"
else
    log_success "✓ Docker already installed"
fi

# Install Azure CLI
if ! command -v az &> /dev/null; then
    log_warn "Installing Azure CLI..."
    curl -sL https://aka.ms/InstallAzureCLIDeb | bash
    log_success "✓ Azure CLI installed"
else
    log_success "✓ Azure CLI already installed"
fi

# Create directories
log_warn "Creating directories..."
mkdir -p /opt/besu/{data,config,keys,logs}
chown -R $SUDO_USER:$SUDO_USER /opt/besu
log_success "✓ Directories created"

# Download genesis file
log_warn "Downloading genesis file..."
if [ -n "$GENESIS_FILE_URL" ]; then
    wget -q -O "$GENESIS_FILE_PATH" "$GENESIS_FILE_URL"
    log_success "✓ Genesis file downloaded"
else
    log_warn "⚠ Genesis file URL not set, using local file"
    if [ -f "$PROJECT_ROOT/config/genesis.json" ]; then
        cp "$PROJECT_ROOT/config/genesis.json" "$GENESIS_FILE_PATH"
        log_success "✓ Genesis file copied"
    else
        log_error "✗ Genesis file not found"
        exit 1
    fi
fi

# Download Besu configuration
log_warn "Downloading Besu configuration..."
CONFIG_FILE="/opt/besu/config/besu-config.toml"

case $NODE_TYPE in
    validator)
        if [ -f "$PROJECT_ROOT/config/validators/besu-config.toml" ]; then
            cp "$PROJECT_ROOT/config/validators/besu-config.toml" "$CONFIG_FILE"
        else
            log_error "✗ Validator config file not found"
            exit 1
        fi
        ;;
    sentry)
        if [ -f "$PROJECT_ROOT/config/sentries/besu-config.toml" ]; then
            cp "$PROJECT_ROOT/config/sentries/besu-config.toml" "$CONFIG_FILE"
        else
            log_error "✗ Sentry config file not found"
            exit 1
        fi
        ;;
    rpc)
        if [ -f "$PROJECT_ROOT/config/rpc/besu-config.toml" ]; then
            cp "$PROJECT_ROOT/config/rpc/besu-config.toml" "$CONFIG_FILE"
        else
            log_error "✗ RPC config file not found"
            exit 1
        fi
        ;;
    *)
        log_error "✗ Invalid node type: $NODE_TYPE"
        exit 1
        ;;
esac

log_success "✓ Configuration file copied"

# Download validator keys from Key Vault (if validator)
if [ "$NODE_TYPE" == "validator" ]; then
    log_warn "Downloading validator keys from Key Vault..."
    # This would use Azure Managed Identity to access Key Vault
    # For now, we'll use a placeholder
    log_warn "⚠ Key download not implemented (requires Key Vault access)"
fi

# Create Docker Compose file
log_warn "Creating Docker Compose file..."
cat > /opt/besu/docker-compose.yml <<EOF
version: '3.8'

services:
  besu:
    image: hyperledger/besu:23.10.0
    container_name: besu-${NODE_TYPE}-${NODE_INDEX}
    restart: unless-stopped
    user: "$SUDO_USER"
    volumes:
      - /opt/besu/data:/data
      - /opt/besu/config:/config
      - /opt/besu/keys:/keys:ro
      - /opt/besu/logs:/logs
    ports:
      - "8545:8545"  # RPC
      - "8546:8546"  # WebSocket
      - "9545:9545"  # Metrics
EOF

if [ "$NODE_TYPE" == "validator" ] || [ "$NODE_TYPE" == "sentry" ]; then
    cat >> /opt/besu/docker-compose.yml <<EOF
      - "30303:30303"  # P2P
      - "30303:30303/udp"  # P2P UDP
EOF
fi

cat >> /opt/besu/docker-compose.yml <<EOF
    command:
      - /opt/besu/bin/besu
      - --config-file=/config/besu-config.toml
    environment:
      - BESU_OPTS=-Xmx4g -Xms4g
    networks:
      - besu-network
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    healthcheck:
      test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:9545/metrics"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 120s

networks:
  besu-network:
    driver: bridge
EOF

chown $SUDO_USER:$SUDO_USER /opt/besu/docker-compose.yml
log_success "✓ Docker Compose file created"

# Create systemd service
log_warn "Creating systemd service..."
cat > /etc/systemd/system/besu.service <<EOF
[Unit]
Description=Besu Node Service
After=docker.service
Requires=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/besu
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
Restart=on-failure
RestartSec=10
User=$SUDO_USER
Group=$SUDO_USER

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable besu.service
log_success "✓ Systemd service created"

# Start Besu service
log_warn "Starting Besu service..."
systemctl start besu.service
log_success "✓ Besu service started"

# Wait for Besu to be ready
log_warn "Waiting for Besu to be ready..."
sleep 30

# Check service status
if systemctl is-active --quiet besu.service; then
    log_success "✓ Besu service is running"
else
    log_error "✗ Besu service failed to start"
    systemctl status besu.service
    exit 1
fi

# Check container status
if docker ps | grep -q "besu-${NODE_TYPE}-${NODE_INDEX}"; then
    log_success "✓ Besu container is running"
else
    log_error "✗ Besu container is not running"
    docker ps -a | grep besu
    exit 1
fi

log_success "Setup complete!"
log_warn "Node type: $NODE_TYPE"
log_warn "Node index: $NODE_INDEX"
log_warn "Logs: /opt/besu/logs"
log_warn "Data: /opt/besu/data"

