#!/usr/bin/env bash
# Verify ChainID 138 Besu node configuration
# Checks that all nodes have correct static-nodes.json and permissioned-nodes.json files
# Verifies discovery settings and peer connections

set -euo pipefail

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

# 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"; }

# Configuration
PROXMOX_HOST="${PROXMOX_HOST:-192.168.11.10}"
BESU_DATA_PATH="${BESU_DATA_PATH:-/var/lib/besu}"
BESU_PERMISSIONS_PATH="${BESU_PERMISSIONS_PATH:-/var/lib/besu/permissions}"

# All Besu nodes for ChainID 138
declare -A BESU_NODES=(
    [1000]="192.168.11.100"
    [1001]="192.168.11.101"
    [1002]="192.168.11.102"
    [1003]="192.168.11.103"
    [1004]="192.168.11.104"
    [1500]="192.168.11.150"
    [1501]="192.168.11.151"
    [1502]="192.168.11.152"
    [1503]="192.168.11.153"
    [1504]="192.168.11.154"
    [2500]="192.168.11.250"
    [2501]="192.168.11.251"
    [2502]="192.168.11.252"
    [2503]="192.168.11.253"  # Ali's RPC node (0x8a)
    [2504]="192.168.11.254"  # Ali's RPC node (0x1)
    [2505]="192.168.11.255"  # Luis's RPC node (0x8a)
    [2506]="192.168.11.256"  # Luis's RPC node (0x1)
    [2507]="192.168.11.257"  # Putu's RPC node (0x8a)
    [2508]="192.168.11.258"  # Putu's RPC node (0x1)
)

# RPC nodes that should have discovery disabled
# These nodes report chainID 0x1 to MetaMask for wallet compatibility
# Discovery is disabled to prevent actual connection to Ethereum mainnet while reporting 0x1 to wallets
DISCOVERY_DISABLED_VMIDS=(2500 2503 2504 2505 2506 2507 2508)

# Check if container is running
check_container() {
    local vmid=$1
    if ! ssh -o StrictHostKeyChecking=accept-new "root@${PROXMOX_HOST}" \
        "pct status $vmid 2>/dev/null | grep -q running"; then
        return 1
    fi
    return 0
}

# Verify file exists and is readable
verify_file() {
    local vmid=$1
    local file_path=$2
    local file_name=$3
    
    if ssh -o StrictHostKeyChecking=accept-new "root@${PROXMOX_HOST}" \
        "pct exec $vmid -- test -f $file_path 2>/dev/null"; then
        log_success "  ✓ $file_name exists"
        
        # Check if file is readable
        if ssh -o StrictHostKeyChecking=accept-new "root@${PROXMOX_HOST}" \
            "pct exec $vmid -- test -r $file_path 2>/dev/null"; then
            log_success "    ✓ File is readable"
            return 0
        else
            log_warn "    ✗ File is not readable"
            return 1
        fi
    else
        log_error "  ✗ $file_name not found: $file_path"
        return 1
    fi
}

# Verify discovery setting
verify_discovery() {
    local vmid=$1
    local should_disable=$2
    
    local config_files=(
        "/etc/besu/config.toml"
        "/etc/besu/config-rpc-core.toml"
        "/etc/besu/config-rpc-perm.toml"
        "/etc/besu/config-rpc-public.toml"
        "/etc/besu/config-rpc-4.toml"
        "/etc/besu/config-validator.toml"
        "/etc/besu/config-sentry.toml"
    )
    
    local found=false
    local discovery_setting=""
    
    for config_file in "${config_files[@]}"; do
        if ssh -o StrictHostKeyChecking=accept-new "root@${PROXMOX_HOST}" \
            "pct exec $vmid -- test -f $config_file 2>/dev/null"; then
            found=true
            discovery_setting=$(ssh -o StrictHostKeyChecking=accept-new "root@${PROXMOX_HOST}" \
                "pct exec $vmid -- grep '^discovery-enabled=' $config_file 2>/dev/null | head -1" || echo "")
            break
        fi
    done
    
    if [[ "$found" == "false" ]]; then
        log_warn "  ✗ No config file found"
        return 1
    fi
    
    if [[ -z "$discovery_setting" ]]; then
        log_warn "  ⚠ Discovery setting not found (using default)"
        return 0
    fi
    
    if [[ "$should_disable" == "true" ]]; then
        if echo "$discovery_setting" | grep -q "discovery-enabled=false"; then
            log_success "  ✓ Discovery is disabled (correct)"
            return 0
        else
            log_error "  ✗ Discovery should be disabled but is: $discovery_setting"
            return 1
        fi
    else
        if echo "$discovery_setting" | grep -q "discovery-enabled=true"; then
            log_success "  ✓ Discovery is enabled (correct)"
            return 0
        else
            log_warn "  ⚠ Discovery setting: $discovery_setting"
            return 0
        fi
    fi
}

# Check peer count via RPC
check_peer_count() {
    local vmid=$1
    local ip=$2
    
    log_info "  Checking peer count via RPC..."
    
    local peer_count
    peer_count=$(ssh -o StrictHostKeyChecking=accept-new "root@${PROXMOX_HOST}" "pct exec $vmid -- curl -s -X POST -H 'Content-Type: application/json' -d '{\"jsonrpc\":\"2.0\",\"method\":\"net_peerCount\",\"params\":[],\"id\":1}' http://localhost:8545 2>/dev/null | python3 -c \"import sys, json; data=json.load(sys.stdin); result=data.get('result', ''); print(int(result, 16) if result else 0)\" 2>/dev/null || echo \"0\"")
    
    if [[ -n "$peer_count" ]] && [[ "$peer_count" != "0" ]]; then
        log_success "    ✓ Peer count: $peer_count"
        return 0
    else
        log_warn "    ⚠ Peer count: $peer_count - may be syncing"
        return 0
    fi
}

# Main verification
main() {
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo "ChainID 138 Besu Configuration Verification"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo ""
    
    local total_nodes=0
    local verified_nodes=0
    local failed_nodes=0
    
    for vmid in "${!BESU_NODES[@]}"; do
        local ip="${BESU_NODES[$vmid]}"
        ((total_nodes++))
        
        echo ""
        echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
        log_info "Verifying VMID $vmid - IP: $ip"
        echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
        
        if ! check_container "$vmid"; then
            log_warn "Container $vmid is not running, skipping..."
            ((failed_nodes++))
            continue
        fi
        
        local node_ok=true
        
        # Verify static-nodes.json
        if ! verify_file "$vmid" "${BESU_DATA_PATH}/static-nodes.json" "static-nodes.json"; then
            node_ok=false
        fi
        
        # Verify permissioned-nodes.json
        if ! verify_file "$vmid" "${BESU_PERMISSIONS_PATH}/permissioned-nodes.json" "permissioned-nodes.json"; then
            node_ok=false
        fi
        
        # Verify discovery setting
        local should_disable=false
        for disabled_vmid in "${DISCOVERY_DISABLED_VMIDS[@]}"; do
            if [[ "$vmid" == "$disabled_vmid" ]]; then
                should_disable=true
                break
            fi
        done
        
        if ! verify_discovery "$vmid" "$should_disable"; then
            node_ok=false
        fi
        
        # Check peer count (if RPC is available)
        check_peer_count "$vmid" "$ip" || true
        
        if [[ "$node_ok" == "true" ]]; then
            log_success "VMID $vmid: Configuration verified"
            ((verified_nodes++))
        else
            log_error "VMID $vmid: Configuration issues found"
            ((failed_nodes++))
        fi
    done
    
    echo ""
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo "Verification Summary"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    log_info "Total nodes: $total_nodes"
    log_success "Verified: $verified_nodes"
    if [[ $failed_nodes -gt 0 ]]; then
        log_error "Failed: $failed_nodes"
    fi
    echo ""
    
    if [[ $failed_nodes -eq 0 ]]; then
        log_success "All nodes verified successfully!"
        return 0
    else
        log_warn "Some nodes have configuration issues"
        return 1
    fi
}

main "$@"

