#!/bin/bash
# avd-resource-checker.sh
# Author: Matthew Raymer
# Date: 2025-01-27
# Description: Check system resources and recommend optimal AVD configuration

set -e

# Source common utilities
source "$(dirname "$0")/common.sh"

# Colors for output
RED_COLOR='\033[0;31m'
GREEN_COLOR='\033[0;32m'
YELLOW_COLOR='\033[1;33m'
BLUE_COLOR='\033[0;34m'
NC_COLOR='\033[0m' # No Color

# Function to print colored output
print_status() {
    local color=$1
    local message=$2
    echo -e "${color}${message}${NC_COLOR}"
}

# Function to get system memory in MB
get_system_memory() {
    if command -v free >/dev/null 2>&1; then
        free -m | awk 'NR==2{print $2}'
    else
        echo "0"
    fi
}

# Function to get available memory in MB
get_available_memory() {
    if command -v free >/dev/null 2>&1; then
        free -m | awk 'NR==2{print $7}'
    else
        echo "0"
    fi
}

# Function to get CPU core count
get_cpu_cores() {
    if command -v nproc >/dev/null 2>&1; then
        nproc
    elif [ -f /proc/cpuinfo ]; then
        grep -c ^processor /proc/cpuinfo
    else
        echo "1"
    fi
}

# Function to check GPU capabilities
check_gpu_capabilities() {
    local gpu_type="unknown"
    local gpu_memory="0"
    
    # Check for NVIDIA GPU
    if command -v nvidia-smi >/dev/null 2>&1; then
        gpu_type="nvidia"
        gpu_memory=$(nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits 2>/dev/null | head -1 || echo "0")
        print_status $GREEN_COLOR "✓ NVIDIA GPU detected (${gpu_memory}MB VRAM)"
        return 0
    fi
    
    # Check for AMD GPU
    if command -v rocm-smi >/dev/null 2>&1; then
        gpu_type="amd"
        print_status $GREEN_COLOR "✓ AMD GPU detected"
        return 0
    fi
    
    # Check for Intel GPU
    if lspci 2>/dev/null | grep -i "vga.*intel" >/dev/null; then
        gpu_type="intel"
        print_status $YELLOW_COLOR "✓ Intel integrated GPU detected"
        return 1
    fi
    
    # Check for generic GPU
    if lspci 2>/dev/null | grep -i "vga" >/dev/null; then
        gpu_type="generic"
        print_status $YELLOW_COLOR "✓ Generic GPU detected"
        return 1
    fi
    
    print_status $RED_COLOR "✗ No GPU detected"
    return 2
}

# Function to check if hardware acceleration is available
check_hardware_acceleration() {
    local gpu_capable=$1
    
    if [ $gpu_capable -eq 0 ]; then
        print_status $GREEN_COLOR "✓ Hardware acceleration recommended"
        return 0
    elif [ $gpu_capable -eq 1 ]; then
        print_status $YELLOW_COLOR "⚠ Limited hardware acceleration"
        return 1
    else
        print_status $RED_COLOR "✗ No hardware acceleration available"
        return 2
    fi
}

# Function to recommend AVD configuration
recommend_avd_config() {
    local total_memory=$1
    local available_memory=$2
    local cpu_cores=$3
    local gpu_capable=$4
    
    print_status $BLUE_COLOR "\n=== AVD Configuration Recommendation ==="
    
    # Calculate recommended memory (leave 2GB for system)
    local system_reserve=2048
    local recommended_memory=$((available_memory - system_reserve))
    
    # Cap memory at reasonable limits
    if [ $recommended_memory -gt 4096 ]; then
        recommended_memory=4096
    elif [ $recommended_memory -lt 1024 ]; then
        recommended_memory=1024
    fi
    
    # Calculate recommended cores (leave 2 cores for system)
    local recommended_cores=$((cpu_cores - 2))
    if [ $recommended_cores -lt 1 ]; then
        recommended_cores=1
    elif [ $recommended_cores -gt 4 ]; then
        recommended_cores=4
    fi
    
    # Determine GPU setting
    local gpu_setting=""
    case $gpu_capable in
        0) gpu_setting="-gpu host" ;;
        1) gpu_setting="-gpu swiftshader_indirect" ;;
        2) gpu_setting="-gpu swiftshader_indirect" ;;
    esac
    
    # Generate recommendation
    print_status $GREEN_COLOR "Recommended AVD Configuration:"
    echo "  Memory: ${recommended_memory}MB"
    echo "  Cores: ${recommended_cores}"
    echo "  GPU: ${gpu_setting}"
    
    # Get AVD name from function parameter (passed from main)
    local avd_name=$5
    local command="emulator -avd ${avd_name} -no-audio -memory ${recommended_memory} -cores ${recommended_cores} ${gpu_setting} &"
    
    print_status $BLUE_COLOR "\nGenerated Command:"
    echo "  ${command}"
    
    # Save to file for easy execution
    local script_file="/tmp/start-avd-${avd_name}.sh"
    cat > "$script_file" << EOF
#!/bin/bash
# Auto-generated AVD startup script
# Generated by avd-resource-checker.sh on $(date)

echo "Starting AVD: ${avd_name}"
echo "Memory: ${recommended_memory}MB"
echo "Cores: ${recommended_cores}"
echo "GPU: ${gpu_setting}"

${command}

echo "AVD started in background"
echo "Check status with: adb devices"
echo "View logs with: adb logcat"
EOF
    
    chmod +x "$script_file"
    print_status $GREEN_COLOR "\n✓ Startup script saved to: ${script_file}"
    
    return 0
}

# Function to test AVD startup
test_avd_startup() {
    local avd_name=$1
    local test_duration=${2:-30}
    
    print_status $BLUE_COLOR "\n=== Testing AVD Startup ==="
    
    # Check if AVD exists
    if ! avdmanager list avd | grep -q "$avd_name"; then
        print_status $RED_COLOR "✗ AVD '$avd_name' not found"
        return 1
    fi
    
    print_status $YELLOW_COLOR "Testing AVD startup for ${test_duration} seconds..."
    
    # Start emulator in test mode
    emulator -avd "$avd_name" -no-audio -no-window -no-snapshot -memory 1024 -cores 1 -gpu swiftshader_indirect &
    local emulator_pid=$!
    
    # Wait for boot
    local boot_time=0
    local max_wait=$test_duration
    
    while [ $boot_time -lt $max_wait ]; do
        if adb devices | grep -q "emulator.*device"; then
            print_status $GREEN_COLOR "✓ AVD booted successfully in ${boot_time} seconds"
            break
        fi
        sleep 2
        boot_time=$((boot_time + 2))
    done
    
    # Cleanup
    kill $emulator_pid 2>/dev/null || true
    adb emu kill 2>/dev/null || true
    
    if [ $boot_time -ge $max_wait ]; then
        print_status $RED_COLOR "✗ AVD failed to boot within ${test_duration} seconds"
        return 1
    fi
    
    return 0
}

# Function to list available AVDs
list_available_avds() {
    print_status $BLUE_COLOR "\n=== Available AVDs ==="
    
    if ! command -v avdmanager >/dev/null 2>&1; then
        print_status $RED_COLOR "✗ avdmanager not found. Please install Android SDK command line tools."
        return 1
    fi
    
    local avd_list=$(avdmanager list avd 2>/dev/null)
    if [ -z "$avd_list" ]; then
        print_status $YELLOW_COLOR "⚠ No AVDs found. Create one with:"
        echo "  avdmanager create avd --name TimeSafari_Emulator --package system-images;android-34;google_apis;x86_64"
        return 1
    fi
    
    echo "$avd_list"
    return 0
}

# Function to create optimized AVD
create_optimized_avd() {
    local avd_name=$1
    local memory=$2
    local cores=$3
    
    print_status $BLUE_COLOR "\n=== Creating Optimized AVD ==="
    
    # Check if system image is available
    local system_image="system-images;android-34;google_apis;x86_64"
    if ! sdkmanager --list | grep -q "$system_image"; then
        print_status $YELLOW_COLOR "Installing system image: $system_image"
        sdkmanager "$system_image"
    fi
    
    # Create AVD
    print_status $YELLOW_COLOR "Creating AVD: $avd_name"
    avdmanager create avd \
        --name "$avd_name" \
        --package "$system_image" \
        --device "pixel_7" \
        --force
    
    # Configure AVD
    local avd_config_file="$HOME/.android/avd/${avd_name}.avd/config.ini"
    if [ -f "$avd_config_file" ]; then
        print_status $YELLOW_COLOR "Configuring AVD settings..."
        
        # Set memory
        sed -i "s/vm.heapSize=.*/vm.heapSize=${memory}/" "$avd_config_file"
        
        # Set cores
        sed -i "s/hw.cpu.ncore=.*/hw.cpu.ncore=${cores}/" "$avd_config_file"
        
        # Disable unnecessary features
        echo "hw.audioInput=no" >> "$avd_config_file"
        echo "hw.audioOutput=no" >> "$avd_config_file"
        echo "hw.camera.back=none" >> "$avd_config_file"
        echo "hw.camera.front=none" >> "$avd_config_file"
        echo "hw.gps=no" >> "$avd_config_file"
        echo "hw.sensors.orientation=no" >> "$avd_config_file"
        echo "hw.sensors.proximity=no" >> "$avd_config_file"
        
        print_status $GREEN_COLOR "✓ AVD configured successfully"
    fi
    
    return 0
}

# Main function
main() {
    print_status $BLUE_COLOR "=== TimeSafari AVD Resource Checker ==="
    print_status $BLUE_COLOR "Checking system resources and recommending optimal AVD configuration\n"
    
    # Get system information
    local total_memory=$(get_system_memory)
    local available_memory=$(get_available_memory)
    local cpu_cores=$(get_cpu_cores)
    
    print_status $BLUE_COLOR "=== System Information ==="
    echo "Total Memory: ${total_memory}MB"
    echo "Available Memory: ${available_memory}MB"
    echo "CPU Cores: ${cpu_cores}"
    
    # Check GPU capabilities
    print_status $BLUE_COLOR "\n=== GPU Analysis ==="
    check_gpu_capabilities
    local gpu_capable=$?
    
    # Check hardware acceleration
    check_hardware_acceleration $gpu_capable
    local hw_accel=$?
    
    # List available AVDs
    list_available_avds
    
    # Get AVD name from user or use default
    local avd_name="TimeSafari_Emulator"
    if [ $# -gt 0 ]; then
        avd_name="$1"
    fi
    
    # Recommend configuration
    recommend_avd_config $total_memory $available_memory $cpu_cores $gpu_capable "$avd_name"
    
    # Test AVD if requested
    if [ "$2" = "--test" ]; then
        test_avd_startup "$avd_name"
    fi
    
    # Create optimized AVD if requested
    if [ "$2" = "--create" ]; then
        local recommended_memory=$((available_memory - 2048))
        if [ $recommended_memory -gt 4096 ]; then
            recommended_memory=4096
        elif [ $recommended_memory -lt 1024 ]; then
            recommended_memory=1024
        fi
        
        local recommended_cores=$((cpu_cores - 2))
        if [ $recommended_cores -lt 1 ]; then
            recommended_cores=1
        elif [ $recommended_cores -gt 4 ]; then
            recommended_cores=4
        fi
        
        create_optimized_avd "$avd_name" $recommended_memory $recommended_cores
    fi
    
    print_status $GREEN_COLOR "\n=== Resource Check Complete ==="
    print_status $YELLOW_COLOR "Tip: Use the generated startup script for consistent AVD launches"
}

# Show help
show_help() {
    echo "Usage: $0 [AVD_NAME] [OPTIONS]"
    echo ""
    echo "Options:"
    echo "  --test     Test AVD startup (30 second test)"
    echo "  --create   Create optimized AVD with recommended settings"
    echo "  --help     Show this help message"
    echo ""
    echo "Examples:"
    echo "  $0                                    # Check resources and recommend config"
    echo "  $0 TimeSafari_Emulator               # Check resources for specific AVD"
    echo "  $0 TimeSafari_Emulator --test         # Test AVD startup"
    echo "  $0 TimeSafari_Emulator --create       # Create optimized AVD"
    echo ""
    echo "The script will:"
    echo "  - Analyze system resources (RAM, CPU, GPU)"
    echo "  - Recommend optimal AVD configuration"
    echo "  - Generate startup command and script"
    echo "  - Optionally test or create AVD"
}

# Parse command line arguments
if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
    show_help
    exit 0
fi

# Run main function
main "$@"
