#!/usr/bin/env bash
# Copy Besu Configuration Files - Enhanced version supporting config/nodes/ structure
# Supports both flat config structure and node-specific directories (Quorum-Genesis-Tool style)

set -euo pipefail

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

# Source common functions if available
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

# Source project directory
SOURCE_PROJECT="${1:-${SOURCE_PROJECT:-../smom-dbis-138}}"
if [[ "$SOURCE_PROJECT" != /* ]]; then
    SOURCE_PROJECT="$(cd "$PROJECT_ROOT" && cd "$SOURCE_PROJECT" && pwd 2>/dev/null || echo "$PROJECT_ROOT/$SOURCE_PROJECT")"
fi

if [[ ! -d "$SOURCE_PROJECT" ]]; then
    error_exit "Source project directory not found: $SOURCE_PROJECT"
fi

log_info "Copying Besu configuration files from: $SOURCE_PROJECT"
log_info "Target containers: Validators (1000-1004), Sentries (1500-1503), RPC (2500-2502)"

# Define container arrays and node name mappings (new ranges)
declare -A VMID_TO_NODE
VMID_TO_NODE[1000]="validator-1"
VMID_TO_NODE[1001]="validator-2"
VMID_TO_NODE[1002]="validator-3"
VMID_TO_NODE[1003]="validator-4"
VMID_TO_NODE[1004]="validator-5"
VMID_TO_NODE[1500]="sentry-1"
VMID_TO_NODE[1501]="sentry-2"
VMID_TO_NODE[1502]="sentry-3"
VMID_TO_NODE[1503]="sentry-4"
VMID_TO_NODE[2500]="rpc-1"
VMID_TO_NODE[2501]="rpc-2"
VMID_TO_NODE[2502]="rpc-3"

VALIDATORS=(1000 1001 1002 1003 1004)
SENTRIES=(1500 1501 1502 1503)
RPCS=(2500 2501 2502)
ALL_BESU=("${VALIDATORS[@]}" "${SENTRIES[@]}" "${RPCS[@]}")

# Check if config/nodes/ structure exists
HAS_NODE_DIRS=false
if [[ -d "$SOURCE_PROJECT/config/nodes" ]]; then
    HAS_NODE_DIRS=true
    log_info "Detected config/nodes/ structure (Quorum-Genesis-Tool style)"
else
    log_info "Using flat config structure"
fi

# Function to copy file to container
copy_to_container() {
    local vmid="$1"
    local source_file="$2"
    local dest_file="$3"
    
    if [[ ! -f "$source_file" ]]; then
        log_warn "Source file not found: $source_file (skipping container $vmid)"
        return 1
    fi
    
    if ! pct status "$vmid" 2>/dev/null | grep -q running; then
        log_warn "Container $vmid is not running (skipping)"
        return 1
    fi
    
    log_info "Copying to container $vmid: $(basename "$source_file") -> $dest_file"
    pct push "$vmid" "$source_file" "$dest_file" || {
        log_error "Failed to copy $source_file to container $vmid"
        return 1
    }
    
    pct exec "$vmid" -- chown besu:besu "$dest_file" 2>/dev/null || true
    return 0
}

# Function to find node-specific config file
find_node_config() {
    local node_name="$1"
    local config_type="$2"  # validator, sentry, rpc
    local vmid="$3"
    
    # Try node-specific directory first
    if [[ "$HAS_NODE_DIRS" == "true" ]]; then
        local node_dir="$SOURCE_PROJECT/config/nodes/$node_name"
        if [[ -d "$node_dir" ]]; then
            # Try config.toml first (common name in node directories)
            if [[ -f "$node_dir/config.toml" ]]; then
                echo "$node_dir/config.toml"
                return 0
            fi
            # Try type-specific names
            if [[ -f "$node_dir/config-${config_type}.toml" ]]; then
                echo "$node_dir/config-${config_type}.toml"
                return 0
            fi
        fi
    fi
    
    # Fall back to flat structure
    case "$config_type" in
        validator)
            for name in "config-validator.toml"; do
                if [[ -f "$SOURCE_PROJECT/config/$name" ]]; then
                    echo "$SOURCE_PROJECT/config/$name"
                    return 0
                fi
            done
            ;;
        sentry)
            for name in "config-sentry.toml" "config-member.toml"; do  # config-member.toml kept as fallback for backwards compatibility
                if [[ -f "$SOURCE_PROJECT/config/$name" ]]; then
                    echo "$SOURCE_PROJECT/config/$name"
                    return 0
                fi
            done
            ;;
        rpc)
            for name in "config-rpc-public.toml" "config-rpc-core.toml"; do
                if [[ -f "$SOURCE_PROJECT/config/$name" ]]; then
                    echo "$SOURCE_PROJECT/config/$name"
                    return 0
                fi
            done
            ;;
    esac
    
    return 1
}

# Copy genesis.json (always from flat structure)
log_info ""
log_info "=== Copying genesis.json ==="
GENESIS_FILE="$SOURCE_PROJECT/config/genesis.json"
if [[ -f "$GENESIS_FILE" ]]; then
    for vmid in "${ALL_BESU[@]}"; do
        copy_to_container "$vmid" "$GENESIS_FILE" "/etc/besu/genesis.json"
    done
    log_success "genesis.json copied to all containers"
else
    log_error "genesis.json not found at: $GENESIS_FILE"
    exit 1
fi

# Copy permissions files (always from flat structure)
log_info ""
log_info "=== Copying permissions files ==="
for perm_file in "permissions-nodes.toml" "permissions-accounts.toml"; do
    PERM_FILE="$SOURCE_PROJECT/config/$perm_file"
    if [[ -f "$PERM_FILE" ]]; then
        for vmid in "${ALL_BESU[@]}"; do
            copy_to_container "$vmid" "$PERM_FILE" "/etc/besu/$perm_file"
        done
        log_success "$perm_file copied to all containers"
    else
        log_warn "$perm_file not found at: $PERM_FILE"
    fi
done

# Copy node-specific config files
log_info ""
log_info "=== Copying node-specific config files ==="

# Validators
for vmid in "${VALIDATORS[@]}"; do
    node_name="${VMID_TO_NODE[$vmid]}"
    config_file=$(find_node_config "$node_name" "validator" "$vmid")
    if [[ -n "$config_file" ]] && [[ -f "$config_file" ]]; then
        copy_to_container "$vmid" "$config_file" "/etc/besu/config-validator.toml"
    else
        log_warn "No config file found for validator $vmid ($node_name)"
    fi
done
log_success "Validator config files copied"

# Sentries
for vmid in "${SENTRIES[@]}"; do
    node_name="${VMID_TO_NODE[$vmid]}"
    config_file=$(find_node_config "$node_name" "sentry" "$vmid")
    if [[ -n "$config_file" ]] && [[ -f "$config_file" ]]; then
        copy_to_container "$vmid" "$config_file" "/etc/besu/config-sentry.toml"
    else
        log_warn "No config file found for sentry $vmid ($node_name)"
    fi
done
log_success "Sentry config files copied"

# RPC nodes - Each VMID maps to a specific RPC type
declare -A RPC_VMID_TO_TYPE
RPC_VMID_TO_TYPE[2500]="core"      # Core RPC
RPC_VMID_TO_TYPE[2501]="perm"      # Permissioned RPC
RPC_VMID_TO_TYPE[2502]="public"    # Public RPC

declare -A RPC_TYPE_TO_CONFIG
RPC_TYPE_TO_CONFIG["core"]="config-rpc-core.toml"
RPC_TYPE_TO_CONFIG["perm"]="config-rpc-perm.toml"
RPC_TYPE_TO_CONFIG["public"]="config-rpc-public.toml"

for vmid in "${RPCS[@]}"; do
    node_name="${VMID_TO_NODE[$vmid]}"
    rpc_type="${RPC_VMID_TO_TYPE[$vmid]}"
    config_filename="${RPC_TYPE_TO_CONFIG[$rpc_type]}"
    
    if [[ -z "$rpc_type" ]] || [[ -z "$config_filename" ]]; then
        log_warn "Unknown RPC type mapping for VMID $vmid, skipping"
        continue
    fi
    
    # Try to find node-specific config first
    config_file=""
    if [[ "$HAS_NODE_DIRS" == "true" ]]; then
        node_dir="$SOURCE_PROJECT/config/nodes/$node_name"
        if [[ -d "$node_dir" ]]; then
            # Try config.toml first (preferred)
            if [[ -f "$node_dir/config.toml" ]]; then
                config_file="$node_dir/config.toml"
            # Try type-specific config file
            elif [[ -f "$node_dir/$config_filename" ]]; then
                config_file="$node_dir/$config_filename"
            fi
        fi
    fi
    
    # Fall back to flat structure if not found
    if [[ -z "$config_file" ]]; then
        # Try exact config file name in flat structure
        if [[ -f "$SOURCE_PROJECT/config/$config_filename" ]]; then
            config_file="$SOURCE_PROJECT/config/$config_filename"
        # Fallback: try alternative names (for backwards compatibility)
        elif [[ "$rpc_type" == "core" ]] && [[ -f "$SOURCE_PROJECT/config/config-rpc-public.toml" ]]; then
            log_warn "Using config-rpc-public.toml as fallback for Core RPC (VMID $vmid)"
            config_file="$SOURCE_PROJECT/config/config-rpc-public.toml"
        fi
    fi
    
    if [[ -n "$config_file" ]] && [[ -f "$config_file" ]]; then
        copy_to_container "$vmid" "$config_file" "/etc/besu/$config_filename"
        log_info "Copied $config_filename to RPC node $vmid ($node_name, type: $rpc_type)"
        
        # Update systemd service file to use the correct config file
        log_info "Updating systemd service to use $config_filename for RPC node $vmid"
        pct exec "$vmid" -- sed -i "s|--config-file=\$BESU_CONFIG/config-rpc-public.toml|--config-file=\$BESU_CONFIG/$config_filename|g" /etc/systemd/system/besu-rpc.service 2>/dev/null || {
            log_warn "Failed to update systemd service file for $vmid (may need manual update)"
        }
        # Reload systemd daemon to pick up changes
        pct exec "$vmid" -- systemctl daemon-reload 2>/dev/null || true
    else
        log_warn "No config file found for RPC $vmid ($node_name, type: $rpc_type, expected: $config_filename)"
    fi
done
log_success "RPC config files copied"

# Copy nodekeys from node directories (if config/nodes/ structure exists)
if [[ "$HAS_NODE_DIRS" == "true" ]]; then
    log_info ""
    log_info "=== Copying nodekeys from config/nodes/ ==="
    
    for vmid in "${ALL_BESU[@]}"; do
        node_name="${VMID_TO_NODE[$vmid]}"
        node_dir="$SOURCE_PROJECT/config/nodes/$node_name"
        
        if [[ -d "$node_dir" ]]; then
            # Copy nodekey if it exists in node directory
            if [[ -f "$node_dir/nodekey" ]]; then
                log_info "Copying nodekey for $node_name (container $vmid)"
                copy_to_container "$vmid" "$node_dir/nodekey" "/data/besu/nodekey"
                pct exec "$vmid" -- chown besu:besu /data/besu/nodekey 2>/dev/null || true
            fi
        fi
    done
    log_success "Nodekeys copied (if present)"
fi

# Copy validator keys (from keys/validators/)
log_info ""
log_info "=== Copying validator keys ==="
KEYS_DIR="$SOURCE_PROJECT/keys/validators"
if [[ -d "$KEYS_DIR" ]]; then
    for vmid in "${VALIDATORS[@]}"; do
        if pct status "$vmid" 2>/dev/null | grep -q running; then
            log_info "Copying validator keys to container $vmid..."
            pct exec "$vmid" -- mkdir -p /keys/validators 2>/dev/null || true
            
            for key_dir in "$KEYS_DIR"/validator-*; do
                if [[ -d "$key_dir" ]]; then
                    validator_name=$(basename "$key_dir")
                    log_info "  Copying $validator_name keys..."
                    tar -C "$KEYS_DIR" -czf /tmp/keys-$$.tar.gz "$validator_name" 2>/dev/null
                    pct push "$vmid" /tmp/keys-$$.tar.gz /tmp/keys-$$.tar.gz
                    pct exec "$vmid" -- mkdir -p "/keys/validators/$validator_name" 2>/dev/null || true
                    pct exec "$vmid" -- tar -xzf /tmp/keys-$$.tar.gz -C /keys/validators/ 2>/dev/null || true
                    pct exec "$vmid" -- rm -f /tmp/keys-$$.tar.gz 2>/dev/null || true
                    rm -f /tmp/keys-$$.tar.gz 2>/dev/null || true
                fi
            done
            
            pct exec "$vmid" -- chown -R besu:besu /keys 2>/dev/null || true
        fi
    done
    log_success "Validator keys copied"
else
    log_warn "Validator keys directory not found at: $KEYS_DIR"
fi

# Create static-nodes.json placeholder (will be updated during bootstrap)
log_info ""
log_info "=== Creating static-nodes.json placeholder ==="
STATIC_NODES_TEMP="/tmp/static-nodes.json"
cat > "$STATIC_NODES_TEMP" <<'EOF'
[]
EOF

for vmid in "${ALL_BESU[@]}"; do
    if pct status "$vmid" 2>/dev/null | grep -q running; then
        copy_to_container "$vmid" "$STATIC_NODES_TEMP" "/etc/besu/static-nodes.json"
    fi
done
rm -f "$STATIC_NODES_TEMP"

log_success "Configuration files copied!"
log_info ""
log_info "Next steps:"
log_info "1. Update static-nodes.json with actual enodes: ./scripts/network/bootstrap-network.sh"
log_info "2. Start services and verify deployment"

