#!/usr/bin/env bash
# Parallel deployment utilities
# Provides functions for parallel container deployment

# Deploy containers in parallel (with limit)
# Usage: parallel_deploy_containers "function_name" "array_of_args" max_parallel
parallel_deploy_containers() {
    local deploy_func="$1"
    local -n args_array="$2"  # Name reference to array
    local max_parallel="${3:-3}"
    local pids=()
    local results=()
    local failed=0
    
    log_info "Deploying ${#args_array[@]} containers with max $max_parallel parallel..."
    
    local i=0
    while [[ $i -lt ${#args_array[@]} ]]; do
        # Wait for slot if we've reached max parallel
        while [[ ${#pids[@]} -ge $max_parallel ]]; do
            for pid_idx in "${!pids[@]}"; do
                local pid="${pids[$pid_idx]}"
                if ! kill -0 "$pid" 2>/dev/null; then
                    # Process finished, wait for it and check result
                    wait "$pid"
                    local exit_code=$?
                    if [[ $exit_code -ne 0 ]]; then
                        log_error "Deployment failed with exit code $exit_code"
                        failed=$((failed + 1))
                    fi
                    unset pids[$pid_idx]
                fi
            done
            # Rebuild array to remove gaps
            pids=("${pids[@]}")
            sleep 0.5
        done
        
        # Start new deployment
        local args="${args_array[$i]}"
        log_info "Starting deployment $((i + 1))/${#args_array[@]}: $args"
        
        # Call deploy function in background
        $deploy_func $args &
        local pid=$!
        pids+=("$pid")
        
        i=$((i + 1))
    done
    
    # Wait for all remaining processes
    for pid in "${pids[@]}"; do
        wait "$pid"
        local exit_code=$?
        if [[ $exit_code -ne 0 ]]; then
            log_error "Deployment failed with exit code $exit_code"
            failed=$((failed + 1))
        fi
    done
    
    if [[ $failed -gt 0 ]]; then
        log_error "$failed deployment(s) failed"
        return 1
    fi
    
    log_success "All ${#args_array[@]} deployments completed successfully"
    return 0
}

# Check if parallel deployment is enabled
is_parallel_enabled() {
    [[ "${PARALLEL_DEPLOY:-false}" == "true" ]] && [[ "${MAX_PARALLEL:-0}" -gt 0 ]]
}

# Get max parallel deployments (default: 3)
get_max_parallel() {
    echo "${MAX_PARALLEL:-3}"
}

# Get max parallel for specific operation type
get_max_parallel_for_op() {
    local op_type="$1"
    case "$op_type" in
        create)
            echo "${MAX_PARALLEL_CREATE:-${MAX_PARALLEL:-10}}"
            ;;
        packages|package)
            echo "${MAX_PARALLEL_PACKAGES:-8}"
            ;;
        start)
            echo "${MAX_PARALLEL_START:-15}"
            ;;
        template)
            echo "${MAX_PARALLEL_TEMPLATE:-15}"
            ;;
        ccip)
            echo "${MAX_PARALLEL_CCIP:-8}"
            ;;
        besu)
            echo "${MAX_PARALLEL_BESU:-12}"
            ;;
        *)
            echo "${MAX_PARALLEL:-10}"
            ;;
    esac
}

