"""Hardware profiling: CPU, RAM, Disk."""

import platform
import sys

import psutil

from bilgeai.profiler.gpu import detect_gpus
from bilgeai.profiler.models import HardwareProfile
from bilgeai.profiler.software import detect_torch_version


def get_hardware_profile() -> HardwareProfile:
    """Collect complete hardware profile."""
    mem = psutil.virtual_memory()
    disk = psutil.disk_usage("/") if platform.system() != "Windows" else psutil.disk_usage("C:\\")

    gpus = detect_gpus()
    torch_version = detect_torch_version()

    return HardwareProfile(
        cpu_cores=psutil.cpu_count(logical=True) or 1,
        cpu_name=_get_cpu_name(),
        ram_total_gb=round(mem.total / (1024**3), 1),
        ram_available_gb=round(mem.available / (1024**3), 1),
        disk_free_gb=round(disk.free / (1024**3), 1),
        gpus=gpus,
        os=_get_os_name(),
        python_version=f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
        torch_version=torch_version,
        cuda_available=any(g.cuda_version is not None for g in gpus),
    )


def _get_os_name() -> str:
    """Get OS name, correctly distinguishing Windows 11 from 10."""
    system = platform.system()
    release = platform.release()
    if system == "Windows" and release == "10":
        build = int(platform.version().split(".")[-1])
        if build >= 22000:
            return "Windows 11"
    return f"{system} {release}"


def _get_cpu_name() -> str:
    """Get CPU model name."""
    try:
        if platform.system() == "Windows":
            return platform.processor() or "Unknown CPU"
        elif platform.system() == "Linux":
            with open("/proc/cpuinfo") as f:
                for line in f:
                    if "model name" in line:
                        return line.split(":")[1].strip()
        elif platform.system() == "Darwin":
            import subprocess

            result = subprocess.run(
                ["sysctl", "-n", "machdep.cpu.brand_string"],
                capture_output=True,
                text=True,
            )
            if result.returncode == 0:
                return result.stdout.strip()
    except Exception:
        pass
    return platform.processor() or "Unknown CPU"
