#!/usr/bin/env bash
# Configure Besu RPC nodes (2500, 2501, 2502) with correct configurations
# This script ensures each RPC node has the correct config based on its role
#
# Node Roles:
#   2500 = Core - No public access, all features enabled (ADMIN, DEBUG, TRACE)
#   2501 = Prv (Permissioned) - Public permissioned access, non-Admin features only
#   2502 = Pub (Public) - Public non-auth access, minimal wallet features

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
CONFIG_DIR="$PROJECT_ROOT/smom-dbis-138/config"

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

log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

# Check if running on Proxmox host
if ! command -v pct &>/dev/null; then
    log_error "This script must be run on Proxmox host (pct command not found)"
    exit 1
fi

# RPC Node Configuration Mapping
declare -A RPC_CONFIGS
RPC_CONFIGS[2500]="config-rpc-core.toml"
RPC_CONFIGS[2501]="config-rpc-perm.toml"
RPC_CONFIGS[2502]="config-rpc-public.toml"

declare -A RPC_ROLES
RPC_ROLES[2500]="Core (no public access, all features)"
RPC_ROLES[2501]="Permissioned (public permissioned, non-Admin features)"
RPC_ROLES[2502]="Public (public non-auth, minimal wallet features)"

echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Besu RPC Nodes Configuration Script"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""

# Function to check if container is running
check_container() {
    local vmid=$1
    if ! pct status "$vmid" 2>/dev/null | grep -q running; then
        log_warn "Container $vmid is not running. Starting..."
        pct start "$vmid" || {
            log_error "Failed to start container $vmid"
            return 1
        }
        sleep 5
    fi
    return 0
}

# Function to copy config file to container
copy_config() {
    local vmid=$1
    local config_file=$2
    local dest_file="/etc/besu/$config_file"
    
    local source_file="$CONFIG_DIR/$config_file"
    if [[ ! -f "$source_file" ]]; then
        log_error "Config file not found: $source_file"
        return 1
    fi
    
    log_info "Copying $config_file to VMID $vmid..."
    pct push "$vmid" "$source_file" "$dest_file" || {
        log_error "Failed to copy config to container $vmid"
        return 1
    }
    
    # Set ownership
    pct exec "$vmid" -- chown besu:besu "$dest_file" 2>/dev/null || true
    
    log_success "Config copied to $vmid"
    return 0
}

# Function to update systemd service file
update_service() {
    local vmid=$1
    local config_file=$2
    
    log_info "Updating systemd service for VMID $vmid..."
    
    # Update service file to use correct config
    pct exec "$vmid" -- sed -i "s|--config-file=\$BESU_CONFIG/[^ ]*|--config-file=\$BESU_CONFIG/$config_file|g" \
        /etc/systemd/system/besu-rpc.service 2>/dev/null || {
        log_warn "Could not update service file (may need manual update)"
    }
    
    pct exec "$vmid" -- systemctl daemon-reload 2>/dev/null || true
}

# Function to verify configuration
verify_config() {
    local vmid=$1
    local expected_config=$2
    local role="${RPC_ROLES[$vmid]}"
    
    log_info "Verifying configuration for VMID $vmid ($role)..."
    
    local config_path="/etc/besu/$expected_config"
    
    # Check if config file exists
    if ! pct exec "$vmid" -- test -f "$config_path" 2>/dev/null; then
        log_error "Config file not found: $config_path"
        return 1
    fi
    
    log_success "Config file exists: $config_path"
    
    # Verify specific settings based on node type
    case $vmid in
        2500)
            # Core: Should have ADMIN, DEBUG, TRACE, discovery disabled
            log_info "  Checking Core RPC settings..."
            if pct exec "$vmid" -- grep -q 'rpc-http-api=.*"ADMIN"' "$config_path" 2>/dev/null; then
                log_success "    ✓ ADMIN API enabled"
            else
                log_warn "    ✗ ADMIN API not found (should be enabled)"
            fi
            
            if pct exec "$vmid" -- grep -q 'discovery-enabled=false' "$config_path" 2>/dev/null; then
                log_success "    ✓ Discovery disabled (no public routing)"
            else
                log_warn "    ✗ Discovery may be enabled (should be disabled)"
            fi
            ;;
        2501)
            # Permissioned: Should NOT have ADMIN, should have account permissions
            log_info "  Checking Permissioned RPC settings..."
            if ! pct exec "$vmid" -- grep -q 'rpc-http-api=.*"ADMIN"' "$config_path" 2>/dev/null; then
                log_success "    ✓ ADMIN API not enabled (correct)"
            else
                log_warn "    ✗ ADMIN API found (should be removed)"
            fi
            
            if pct exec "$vmid" -- grep -q 'permissions-accounts-config-file-enabled=true' "$config_path" 2>/dev/null; then
                log_success "    ✓ Account permissions enabled"
            else
                log_warn "    ✗ Account permissions not enabled"
            fi
            ;;
        2502)
            # Public: Should have minimal APIs (ETH, NET, WEB3 only)
            log_info "  Checking Public RPC settings..."
            local api_line=$(pct exec "$vmid" -- grep 'rpc-http-api=' "$config_path" 2>/dev/null || echo "")
            if echo "$api_line" | grep -q '"ETH"' && \
               echo "$api_line" | grep -q '"NET"' && \
               echo "$api_line" | grep -q '"WEB3"' && \
               ! echo "$api_line" | grep -q '"ADMIN"'; then
                log_success "    ✓ Minimal APIs enabled (ETH, NET, WEB3)"
            else
                log_warn "    ✗ API configuration may not be minimal"
            fi
            
            if ! pct exec "$vmid" -- grep -q 'permissions-accounts-config-file-enabled=true' "$config_path" 2>/dev/null; then
                log_success "    ✓ No account permissions (public non-auth)"
            else
                log_warn "    ✗ Account permissions enabled (should be disabled for public)"
            fi
            ;;
    esac
    
    return 0
}

# Function to check if nodes are reversed
check_reversed() {
    log_info ""
    log_info "Checking if 2501 and 2502 are reversed..."
    
    local vmid_2501_config=$(pct exec 2501 -- grep 'rpc-http-api=' /etc/besu/config-rpc-perm.toml 2>/dev/null | head -1 || echo "")
    local vmid_2502_config=$(pct exec 2502 -- grep 'rpc-http-api=' /etc/besu/config-rpc-public.toml 2>/dev/null | head -1 || echo "")
    
    # Check if 2501 has ADMIN (shouldn't) or 2502 has more than minimal APIs
    if echo "$vmid_2501_config" | grep -q '"ADMIN"'; then
        log_warn "VMID 2501 has ADMIN API - may need to check if reversed"
    fi
    
    if echo "$vmid_2502_config" | grep -q '"ADMIN"\|"TXPOOL"\|"QBFT"'; then
        log_warn "VMID 2502 has non-minimal APIs - may need to check if reversed"
    fi
    
    log_info "Current configuration check complete"
}

# Main deployment
main() {
    log_info "Starting RPC nodes configuration..."
    log_info ""
    
    # Process each RPC node
    for vmid in 2500 2501 2502; do
        echo ""
        echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
        log_info "Processing VMID $vmid: ${RPC_ROLES[$vmid]}"
        echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
        
        # Check container
        if ! check_container "$vmid"; then
            log_error "Skipping VMID $vmid (container not available)"
            continue
        fi
        
        # Get config file
        local config_file="${RPC_CONFIGS[$vmid]}"
        if [[ -z "$config_file" ]]; then
            log_error "No config mapping for VMID $vmid"
            continue
        fi
        
        # Stop service
        log_info "Stopping Besu service..."
        pct exec "$vmid" -- systemctl stop besu-rpc.service 2>/dev/null || true
        sleep 2
        
        # Copy config
        if ! copy_config "$vmid" "$config_file"; then
            log_error "Failed to copy config for VMID $vmid"
            continue
        fi
        
        # Update service
        update_service "$vmid" "$config_file"
        
        # Verify config
        verify_config "$vmid" "$config_file"
        
        # Start service
        log_info "Starting Besu service..."
        pct exec "$vmid" -- systemctl start besu-rpc.service 2>/dev/null || {
            log_error "Failed to start service on VMID $vmid"
            log_info "Check logs: pct exec $vmid -- journalctl -u besu-rpc.service -n 50"
            continue
        }
        
        sleep 3
        
        # Check service status
        if pct exec "$vmid" -- systemctl is-active --quiet besu-rpc.service 2>/dev/null; then
            log_success "Service started successfully on VMID $vmid"
        else
            log_warn "Service may not be running on VMID $vmid"
            log_info "Check status: pct exec $vmid -- systemctl status besu-rpc.service"
        fi
    done
    
    # Check if reversed
    check_reversed
    
    echo ""
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    log_success "Configuration complete!"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo ""
    log_info "Next steps:"
    log_info "1. Verify services are running:"
    log_info "   pct exec 2500 -- systemctl status besu-rpc.service"
    log_info "   pct exec 2501 -- systemctl status besu-rpc.service"
    log_info "   pct exec 2502 -- systemctl status besu-rpc.service"
    log_info ""
    log_info "2. Test RPC endpoints:"
    log_info "   curl -X POST http://192.168.11.250:8545 -H 'Content-Type: application/json' --data '{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"params\":[],\"id\":1}'"
    log_info ""
    log_info "3. Check logs if issues:"
    log_info "   pct exec 2500 -- journalctl -u besu-rpc.service -f"
}

# Run main function
main "$@"

