import platform
import psutil
import subprocess
from typing import Dict, Any

def get_system_ram_gb() -> float:
    """Returns total system RAM in gigabytes."""
    ram_bytes = psutil.virtual_memory().total
    return ram_bytes / (1024 ** 3)

def is_apple_silicon() -> bool:
    """Checks if the system is running on Apple Silicon (M1/M2/M3/M4)."""
    is_mac = platform.system() == "Darwin"
    is_arm = platform.machine() == "arm64"
    return is_mac and is_arm

def get_nvidia_gpu_info() -> Dict[str, Any]:
    """
    Attempts to get NVIDIA GPU info using nvidia-smi.
    Returns a dict with 'has_gpu' and 'total_vram_gb'.
    """
    try:
        # Run nvidia-smi to get total memory in MiB
        result = subprocess.run(
            [
                "nvidia-smi",
                "--query-gpu=memory.total",
                "--format=csv,noheader,nounits"
            ],
            capture_output=True,
            text=True,
            check=True
        )
        
        # Parse output (could be multiple GPUs, but we'll sum them or just take total)
        lines = result.stdout.strip().split('\n')
        total_vram_mib = sum(int(line.strip()) for line in lines if line.strip().isdigit())
        total_vram_gb = total_vram_mib / 1024.0
        
        return {
            "has_gpu": total_vram_gb > 0,
            "total_vram_gb": total_vram_gb
        }
    except (subprocess.CalledProcessError, FileNotFoundError, ValueError):
        # nvidia-smi not found or failed
        return {
            "has_gpu": False,
            "total_vram_gb": 0.0
        }

def get_hardware_profile() -> Dict[str, Any]:
    """
    Returns a unified profile of the hardware.
    """
    sys_ram = get_system_ram_gb()
    apple_silicon = is_apple_silicon()
    nvidia_info = get_nvidia_gpu_info()
    
    return {
        "os": platform.system(),
        "is_apple_silicon": apple_silicon,
        "system_ram_gb": sys_ram,
        "has_nvidia_gpu": nvidia_info["has_gpu"],
        "nvidia_vram_gb": nvidia_info["total_vram_gb"],
        # On Apple Silicon, system RAM is unified memory
        "unified_memory_gb": sys_ram if apple_silicon else 0.0
    }
