#!/usr/bin/env bash
# Fix Besu services - ensure all services are enabled and running
# Checks service status, validates configuration, and starts services if needed

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# PROJECT_ROOT should be one level up from scripts directory
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"

# Source common functions
if [[ -f "$PROJECT_ROOT/lib/common.sh" ]]; then
    source "$PROJECT_ROOT/lib/common.sh"
else
    log_info() { echo "[INFO] $1"; }
    log_success() { echo "[✓] $1"; }
    log_warn() { echo "[WARNING] $1"; }
    log_error() { echo "[ERROR] $1"; exit 1; }
    error_exit() { echo "[ERROR] $1"; exit 1; }
fi

load_config 2>/dev/null || true

# Container arrays
VALIDATORS=(1000 1001 1002 1003 1004)
SENTRIES=(1500 1501 1502 1503)
RPCS=(2500 2501 2502)

# Service names
declare -A VMID_SERVICE
for vmid in "${VALIDATORS[@]}"; do
    VMID_SERVICE[$vmid]="besu-validator"
done
for vmid in "${SENTRIES[@]}"; do
    VMID_SERVICE[$vmid]="besu-sentry"
done
for vmid in "${RPCS[@]}"; do
    VMID_SERVICE[$vmid]="besu-rpc"
done

log_info "Fixing Besu services - checking and starting services on all containers"

# Check if running on Proxmox host
if ! command_exists pct; then
    error_exit "This script must be run on Proxmox host (pct command not found)"
fi

check_root

# Function to check and fix service on a container
fix_service() {
    local vmid="$1"
    local service_name="${VMID_SERVICE[$vmid]}"
    
    if ! pct list | grep -q "^\s*$vmid\s"; then
        log_warn "Container $vmid does not exist, skipping"
        return 1
    fi
    
    if ! pct status "$vmid" 2>/dev/null | grep -q "status: running"; then
        log_warn "Container $vmid is not running, skipping"
        return 1
    fi
    
    log_info "Checking service $service_name on container $vmid"
    
    # Check if service file exists
    if ! pct exec "$vmid" -- systemctl list-unit-files 2>/dev/null | grep -q "$service_name.service"; then
        log_error "Service $service_name.service not found on container $vmid"
        return 1
    fi
    
    # Check if service is enabled
    if ! pct exec "$vmid" -- systemctl is-enabled "$service_name.service" 2>/dev/null | grep -q "enabled"; then
        log_info "Enabling service $service_name on container $vmid"
        pct exec "$vmid" -- systemctl enable "$service_name.service" 2>/dev/null || {
            log_error "Failed to enable service $service_name on container $vmid"
            return 1
        }
        log_success "Service $service_name enabled on container $vmid"
    fi
    
    # Check service status
    local status=$(pct exec "$vmid" -- systemctl is-active "$service_name.service" 2>/dev/null || echo "inactive")
    
    if [[ "$status" == "active" ]]; then
        log_success "Service $service_name is running on container $vmid"
        
        # Check if service is actually responding (quick health check)
        if [[ "$service_name" == "besu-rpc" ]]; then
            # For RPC nodes, check if RPC port is listening
            if pct exec "$vmid" -- netstat -tln 2>/dev/null | grep -q ":8545"; then
                log_success "RPC port 8545 is listening on container $vmid"
            else
                log_warn "RPC port 8545 not listening on container $vmid (service may still be starting)"
            fi
        fi
        
        # Check metrics port (all Besu nodes should have this)
        if pct exec "$vmid" -- netstat -tln 2>/dev/null | grep -q ":9545"; then
            log_success "Metrics port 9545 is listening on container $vmid"
        else
            log_warn "Metrics port 9545 not listening on container $vmid"
        fi
    else
        log_info "Service $service_name is not running, attempting to start..."
        
        # Check for common issues before starting
        local config_file=""
        case "$service_name" in
            besu-validator)
                config_file="/etc/besu/config-validator.toml"
                ;;
            besu-sentry)
                config_file="/etc/besu/config-sentry.toml"
                ;;
            besu-rpc)
                # RPC nodes may use different config files
                if pct exec "$vmid" -- test -f "/etc/besu/config-rpc-core.toml" 2>/dev/null; then
                    config_file="/etc/besu/config-rpc-core.toml"
                elif pct exec "$vmid" -- test -f "/etc/besu/config-rpc-public.toml" 2>/dev/null; then
                    config_file="/etc/besu/config-rpc-public.toml"
                else
                    config_file="/etc/besu/config-rpc-public.toml"  # Default
                fi
                ;;
        esac
        
        if [[ -n "$config_file" ]]; then
            if ! pct exec "$vmid" -- test -f "$config_file" 2>/dev/null; then
                log_error "Configuration file $config_file not found on container $vmid"
                log_info "Run copy-besu-config.sh to copy configuration files"
                return 1
            fi
        fi
        
        # Check if genesis.json exists
        if ! pct exec "$vmid" -- test -f "/etc/besu/genesis.json" 2>/dev/null; then
            log_error "genesis.json not found on container $vmid"
            log_info "Run copy-besu-config.sh to copy genesis.json"
            return 1
        fi
        
        # Start the service
        if pct exec "$vmid" -- systemctl start "$service_name.service" 2>/dev/null; then
            log_success "Started service $service_name on container $vmid"
            
            # Wait a bit and check status
            sleep 3
            status=$(pct exec "$vmid" -- systemctl is-active "$service_name.service" 2>/dev/null || echo "inactive")
            if [[ "$status" == "active" ]]; then
                log_success "Service $service_name is now running on container $vmid"
            else
                log_warn "Service $service_name started but may have issues (status: $status)"
                log_info "Check logs: pct exec $vmid -- journalctl -u $service_name -n 50"
            fi
        else
            log_error "Failed to start service $service_name on container $vmid"
            log_info "Check logs: pct exec $vmid -- journalctl -u $service_name -n 50"
            return 1
        fi
    fi
    
    return 0
}

# Process all containers
processed=0
failed=0
all_vmids=("${VALIDATORS[@]}" "${SENTRIES[@]}" "${RPCS[@]}")

for vmid in "${all_vmids[@]}"; do
    if fix_service "$vmid"; then
        processed=$((processed + 1))
    else
        failed=$((failed + 1))
    fi
    echo ""  # Blank line between containers
done

log_success "Service check completed!"
log_info "Summary:"
log_info "  Processed: $processed containers"
if [[ $failed -gt 0 ]]; then
    log_warn "  Failed: $failed containers"
fi
log_info ""
log_info "To check service status manually:"
log_info "  pct exec <vmid> -- systemctl status <service-name>"
log_info "  pct exec <vmid> -- journalctl -u <service-name> -f"

