#!/bin/bash
# Hive AI Multi-Environment Management Script
# Bash script for managing multiple Hive AI environments
# Usage: ./manage-hive-environments.sh deploy-all configs

set -euo pipefail

# Configuration
declare -A ENVIRONMENTS=(
    ["development"]="dev.yaml:HIVE_LICENSE_KEY,OPENROUTER_API_KEY:HIVE_DEBUG"
    ["staging"]="staging.yaml:HIVE_LICENSE_KEY,OPENROUTER_API_KEY:"
    ["production"]="prod.yaml:HIVE_LICENSE_KEY,OPENROUTER_API_KEY,PROD_BACKUP_KEY:"
)

# Default values
ACTION=""
CONFIG_DIR="configs"
ENVIRONMENT=""
FORCE=false
PARALLEL=false
LOG_FILE="hive-environments-$(date +%Y%m%d-%H%M%S).log"

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

function usage() {
    cat << EOF
Usage: $0 ACTION [OPTIONS]

Actions:
    deploy-all      Deploy all environments
    validate-all    Validate all environment configurations
    export-all      Export all current configurations
    list           List available environments
    compare        Compare configuration with current (requires -e)

Options:
    -d, --config-dir    Configuration directory (default: configs)
    -e, --environment   Specific environment for compare action
    -f, --force         Skip confirmation prompts
    -p, --parallel      Run operations in parallel (where supported)
    -h, --help          Show this help message

Examples:
    $0 deploy-all
    $0 validate-all -d /path/to/configs
    $0 compare -e production
    $0 list
EOF
}

function log() {
    local level=${2:-INFO}
    local message="$1"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local color=""
    
    case $level in
        ERROR) color=$RED ;;
        SUCCESS) color=$GREEN ;;
        WARN) color=$YELLOW ;;
        INFO) color=$BLUE ;;
        *) color=$NC ;;
    esac
    
    echo -e "${color}[$timestamp] [$level] $message${NC}"
    echo "[$timestamp] [$level] $message" >> "$LOG_FILE"
}

function parse_env_config() {
    local env_name="$1"
    local config_string="${ENVIRONMENTS[$env_name]}"
    
    IFS=':' read -r config_file required_vars optional_vars <<< "$config_string"
    
    echo "$config_file:$required_vars:$optional_vars"
}

function check_environment_variables() {
    local env_name="$1"
    local config_info
    config_info=$(parse_env_config "$env_name")
    
    IFS=':' read -r config_file required_vars optional_vars <<< "$config_info"
    
    local missing_vars=()
    
    if [[ -n "$required_vars" ]]; then
        IFS=',' read -ra REQUIRED <<< "$required_vars"
        for var in "${REQUIRED[@]}"; do
            if [[ -z "${!var:-}" ]]; then
                missing_vars+=("$var")
            fi
        done
    fi
    
    if [[ ${#missing_vars[@]} -gt 0 ]]; then
        log "Missing required environment variables for $env_name: ${missing_vars[*]}" ERROR
        return 1
    fi
    
    log "Environment variables validated for $env_name" SUCCESS
    return 0
}

function deploy_environment() {
    local env_name="$1"
    
    log "Deploying environment: $env_name"
    
    local config_info
    config_info=$(parse_env_config "$env_name")
    
    IFS=':' read -r config_file required_vars optional_vars <<< "$config_info"
    
    local config_path="$CONFIG_DIR/$config_file"
    
    if [[ ! -f "$config_path" ]]; then
        log "Configuration file not found: $config_path" ERROR
        return 1
    fi
    
    if ! check_environment_variables "$env_name"; then
        return 1
    fi
    
    # Deploy using the main deployment script
    local deploy_script
    deploy_script="$(dirname "$0")/deploy-hive-config.sh"
    
    local deploy_args=(-e "$env_name" -c "$config_path")
    
    if [[ "$FORCE" == true ]]; then
        deploy_args+=(-f)
    fi
    
    if [[ -x "$deploy_script" ]]; then
        if "$deploy_script" "${deploy_args[@]}"; then
            log "Successfully deployed $env_name" SUCCESS
            return 0
        else
            log "Failed to deploy $env_name" ERROR
            return 1
        fi
    else
        log "Deploy script not found or not executable: $deploy_script" ERROR
        return 1
    fi
}

function validate_environment() {
    local env_name="$1"
    
    local config_info
    config_info=$(parse_env_config "$env_name")
    
    IFS=':' read -r config_file required_vars optional_vars <<< "$config_info"
    
    local config_path="$CONFIG_DIR/$config_file"
    
    if [[ ! -f "$config_path" ]]; then
        log "$env_name: Configuration file not found" ERROR
        return 1
    fi
    
    if hive config validate "$config_path" >> "$LOG_FILE" 2>&1; then
        log "$env_name: Configuration valid" SUCCESS
        return 0
    else
        log "$env_name: Configuration invalid" ERROR
        return 1
    fi
}

function export_environment() {
    local env_name="$1"
    
    local export_path="export-$env_name-$(date +%Y%m%d-%H%M%S).yaml"
    
    if hive config export "$export_path" >> "$LOG_FILE" 2>&1; then
        log "$env_name: Configuration exported to $export_path" SUCCESS
        return 0
    else
        log "$env_name: Export failed" ERROR
        return 1
    fi
}

function deploy_all() {
    log "Deploying all environments..."
    
    local results=()
    local pids=()
    
    for env in "${!ENVIRONMENTS[@]}"; do
        if [[ "$PARALLEL" == true ]]; then
            # Deploy in background for parallel execution
            (deploy_environment "$env" && echo "$env:SUCCESS" || echo "$env:FAILED") &
            pids+=($!)
        else
            if deploy_environment "$env"; then
                results+=("$env:SUCCESS")
            else
                results+=("$env:FAILED")
            fi
        fi
    done
    
    # Wait for parallel jobs to complete
    if [[ "$PARALLEL" == true ]]; then
        for pid in "${pids[@]}"; do
            wait "$pid"
        done
        
        # Collect results from background jobs
        # Note: This is a simplified version. In practice, you'd want better result collection.
        results=("parallel execution completed")
    fi
    
    # Print summary
    log "Deployment Summary:"
    for result in "${results[@]}"; do
        IFS=':' read -r env status <<< "$result"
        if [[ "$status" == "SUCCESS" ]]; then
            log "  $env: $status" SUCCESS
        else
            log "  $env: $status" ERROR
        fi
    done
}

function validate_all() {
    log "Validating all environments..."
    
    for env in "${!ENVIRONMENTS[@]}"; do
        validate_environment "$env"
    done
}

function export_all() {
    log "Exporting all environments..."
    
    for env in "${!ENVIRONMENTS[@]}"; do
        export_environment "$env"
    done
}

function list_environments() {
    log "Available environments:"
    
    for env in "${!ENVIRONMENTS[@]}"; do
        local config_info
        config_info=$(parse_env_config "$env")
        
        IFS=':' read -r config_file required_vars optional_vars <<< "$config_info"
        
        log "  $env: $config_file" INFO
        if [[ -n "$required_vars" ]]; then
            log "    Required vars: $required_vars"
        fi
        if [[ -n "$optional_vars" ]]; then
            log "    Optional vars: $optional_vars"
        fi
    done
}

function compare_environment() {
    if [[ -z "$ENVIRONMENT" ]]; then
        log "Please specify -e ENVIRONMENT for comparison" ERROR
        return 1
    fi
    
    if [[ ! -v "ENVIRONMENTS[$ENVIRONMENT]" ]]; then
        log "Unknown environment: $ENVIRONMENT" ERROR
        return 1
    fi
    
    local config_info
    config_info=$(parse_env_config "$ENVIRONMENT")
    
    IFS=':' read -r config_file required_vars optional_vars <<< "$config_info"
    
    local config_path="$CONFIG_DIR/$config_file"
    
    hive config diff "$config_path"
}

# Parse command line arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        deploy-all|validate-all|export-all|list|compare)
            ACTION="$1"
            shift
            ;;
        -d|--config-dir)
            CONFIG_DIR="$2"
            shift 2
            ;;
        -e|--environment)
            ENVIRONMENT="$2"
            shift 2
            ;;
        -f|--force)
            FORCE=true
            shift
            ;;
        -p|--parallel)
            PARALLEL=true
            shift
            ;;
        -h|--help)
            usage
            exit 0
            ;;
        *)
            log "Unknown option: $1" ERROR
            usage
            exit 1
            ;;
    esac
done

# Validate required arguments
if [[ -z "$ACTION" ]]; then
    log "Missing required action" ERROR
    usage
    exit 1
fi

# Execute the requested action
case $ACTION in
    deploy-all)
        deploy_all
        ;;
    validate-all)
        validate_all
        ;;
    export-all)
        export_all
        ;;
    list)
        list_environments
        ;;
    compare)
        compare_environment
        ;;
    *)
        log "Unknown action: $ACTION" ERROR
        exit 1
        ;;
esac