#Requires -Version 7.4

function Get-HypervisorPlatformData {
    <#
    .SYNOPSIS
        Detects the hypervisor platform the system is running on.

    .DESCRIPTION
        Uses a two-tier detection architecture to identify the hypervisor:
        - Tier 1: WMI/CIM Manufacturer check (handles 95%+ of cases)
        - Tier 2: Fallback checks via registry, services, drivers, and BIOS

        Detection order is critical: VMware -> NutanixAHV -> XenServer -> Hyper-V

    .OUTPUTS
        [hashtable] with properties:
            IsVMware     - $true if running on VMware
            IsNutanixAHV - $true if running on Nutanix AHV
            IsXenServer  - $true if running on XenServer/Citrix Hypervisor
            IsHyperV     - $true if running on Microsoft Hyper-V
            Hypervisor   - Friendly name string, or $null for bare metal

    .EXAMPLE
        $platform = Get-HypervisorPlatformData
        if ($platform.IsVMware) {
            Write-Host "Running on VMware"
        }

    .EXAMPLE
        $platform = Get-HypervisorPlatformData
        switch ($platform.Hypervisor) {
            'VMware'     { # VMware-specific logic }
            'NutanixAHV' { # Nutanix-specific logic }
            'XenServer'  { # XenServer-specific logic }
            'Hyper-V'    { # Hyper-V-specific logic }
            default      { # Bare metal or unknown }
        }
    #>
    [CmdletBinding()]
    [OutputType([hashtable])]
    param()

    Write-vSEALLog -Message "Starting hypervisor platform detection..." -Level 'VERBOSE'

    # Initialize result structure
    $result = @{
        IsVMware     = $false
        IsNutanixAHV = $false
        IsXenServer  = $false
        IsHyperV     = $false
        Hypervisor   = $null
    }

    # ============================================================
    # TIER 1: WMI Manufacturer Check (single CIM call, handles 95%+)
    # ============================================================
    $computerSystem = $null
    try {
        $computerSystem = Get-CimInstance -ClassName Win32_ComputerSystem -ErrorAction Stop
        Write-vSEALLog -Message "Manufacturer: $($computerSystem.Manufacturer), Model: $($computerSystem.Model)" -Level 'VERBOSE'
    }
    catch {
        Write-vSEALLog -Message "Failed to query Win32_ComputerSystem: $_" -Level 'VERBOSE'
    }

    if ($computerSystem) {
        switch ($computerSystem.Manufacturer) {
            'VMware, Inc.' {
                Write-vSEALLog -Message "Detected VMware via WMI manufacturer" -Level 'VERBOSE'
                $result.IsVMware = $true
                $result.Hypervisor = 'VMware'
                return $result
            }
            'Nutanix' {
                Write-vSEALLog -Message "Detected NutanixAHV via WMI manufacturer" -Level 'VERBOSE'
                $result.IsNutanixAHV = $true
                $result.Hypervisor = 'NutanixAHV'
                return $result
            }
            'Xen' {
                Write-vSEALLog -Message "Detected XenServer via WMI manufacturer" -Level 'VERBOSE'
                $result.IsXenServer = $true
                $result.Hypervisor = 'XenServer'
                return $result
            }
            'Microsoft Corporation' {
                if ($computerSystem.Model -eq 'Virtual Machine') {
                    Write-vSEALLog -Message "Detected Hyper-V via WMI manufacturer and model" -Level 'VERBOSE'
                    $result.IsHyperV = $true
                    $result.Hypervisor = 'Hyper-V'
                    return $result
                }
            }
        }
    }

    # ============================================================
    # TIER 2: Fallback Checks
    # Order is CRITICAL: VMware -> NutanixAHV -> XenServer -> Hyper-V
    # ============================================================
    Write-vSEALLog -Message "Tier 1 detection inconclusive, proceeding to Tier 2 fallback checks..." -Level 'VERBOSE'

    # -----------------------------
    # VMware Fallback
    # -----------------------------
    # 1. Registry check
    if (Test-Path -Path 'HKLM:\SOFTWARE\VMware, Inc.\VMware Tools') {
        Write-vSEALLog -Message "Detected VMware via registry key (VMware Tools)" -Level 'VERBOSE'
        $result.IsVMware = $true
        $result.Hypervisor = 'VMware'
        return $result
    }

    # 2. Service check
    if (Test-vSEALServiceExists -Name 'VMTools') {
        Write-vSEALLog -Message "Detected VMware via VMTools service" -Level 'VERBOSE'
        $result.IsVMware = $true
        $result.Hypervisor = 'VMware'
        return $result
    }

    # 3. BIOS Serial check
    try {
        $bios = Get-CimInstance -ClassName Win32_BIOS -ErrorAction Stop
        if ($bios.SerialNumber -like 'VMware-*') {
            Write-vSEALLog -Message "Detected VMware via BIOS serial number" -Level 'VERBOSE'
            $result.IsVMware = $true
            $result.Hypervisor = 'VMware'
            return $result
        }
    }
    catch {
        Write-vSEALLog -Message "Failed to query Win32_BIOS for VMware detection: $_" -Level 'VERBOSE'
    }

    # -----------------------------
    # NutanixAHV Fallback
    # -----------------------------
    # 1. Disk model contains "NUTANIX"
    try {
        $disks = Get-CimInstance -ClassName Win32_DiskDrive -ErrorAction Stop
        $nutanixDisk = $disks | Where-Object { $_.Model -like '*NUTANIX*' }
        if ($nutanixDisk) {
            Write-vSEALLog -Message "Detected NutanixAHV via disk model containing NUTANIX" -Level 'VERBOSE'
            $result.IsNutanixAHV = $true
            $result.Hypervisor = 'NutanixAHV'
            return $result
        }

        # 2. vioscsi driver running AND disk model contains "NUTANIX" or "VDISK"
        $vioscsiDriver = Get-CimInstance -ClassName Win32_SystemDriver -Filter "Name='vioscsi'" -ErrorAction SilentlyContinue
        if ($vioscsiDriver -and $vioscsiDriver.State -eq 'Running') {
            $vdiskDisk = $disks | Where-Object { $_.Model -like '*VDISK*' -or $_.Model -like '*NUTANIX*' }
            if ($vdiskDisk) {
                Write-vSEALLog -Message "Detected NutanixAHV via vioscsi driver with VDISK/NUTANIX disk" -Level 'VERBOSE'
                $result.IsNutanixAHV = $true
                $result.Hypervisor = 'NutanixAHV'
                return $result
            }
        }
    }
    catch {
        Write-vSEALLog -Message "Failed to query disk/driver info for NutanixAHV detection: $_" -Level 'VERBOSE'
    }

    # -----------------------------
    # XenServer Fallback
    # -----------------------------
    # 1. Services check (XenSvc or xenagent)
    if (Test-vSEALServiceExists -Name 'XenSvc') {
        Write-vSEALLog -Message "Detected XenServer via XenSvc service" -Level 'VERBOSE'
        $result.IsXenServer = $true
        $result.Hypervisor = 'XenServer'
        return $result
    }

    if (Test-vSEALServiceExists -Name 'xenagent') {
        Write-vSEALLog -Message "Detected XenServer via xenagent service" -Level 'VERBOSE'
        $result.IsXenServer = $true
        $result.Hypervisor = 'XenServer'
        return $result
    }

    # 2. Drivers check (xenbus, xennet, xenvbd)
    foreach ($driverName in @('xenbus', 'xennet', 'xenvbd')) {
        try {
            $driver = Get-CimInstance -ClassName Win32_SystemDriver -Filter "Name='$driverName'" -ErrorAction SilentlyContinue
            if ($driver -and $driver.State -eq 'Running') {
                Write-vSEALLog -Message "Detected XenServer via $driverName driver" -Level 'VERBOSE'
                $result.IsXenServer = $true
                $result.Hypervisor = 'XenServer'
                return $result
            }
        }
        catch {
            Write-vSEALLog -Message "Failed to query $driverName driver: $_" -Level 'VERBOSE'
        }
    }

    # 3. Registry check
    if (Test-Path -Path 'HKLM:\SOFTWARE\Citrix\XenTools') {
        Write-vSEALLog -Message "Detected XenServer via registry key (XenTools)" -Level 'VERBOSE'
        $result.IsXenServer = $true
        $result.Hypervisor = 'XenServer'
        return $result
    }

    # -----------------------------
    # Hyper-V Fallback (MUST BE LAST - most false-positive prone)
    # -----------------------------
    # 1. Registry check
    if (Test-Path -Path 'HKLM:\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters') {
        Write-vSEALLog -Message "Detected Hyper-V via registry key (Guest Parameters)" -Level 'VERBOSE'
        $result.IsHyperV = $true
        $result.Hypervisor = 'Hyper-V'
        return $result
    }

    # 2. Services check - MUST check STATUS, not just existence!
    # CRITICAL: vmic* services exist on ALL platforms but only RUN on actual Hyper-V
    foreach ($serviceName in @('vmicheartbeat', 'vmicshutdown', 'vmictimesync')) {
        $service = Test-vSEALServiceExists -Name $serviceName -PassThru
        if ($service -and $service.Status -eq 'Running') {
            Write-vSEALLog -Message "Detected Hyper-V via running $serviceName service" -Level 'VERBOSE'
            $result.IsHyperV = $true
            $result.Hypervisor = 'Hyper-V'
            return $result
        }
    }

    # 3. BIOS check (contains "Hyper-V" or "VRTUAL")
    try {
        $bios = Get-CimInstance -ClassName Win32_BIOS -ErrorAction Stop
        $biosVersion = $bios.SMBIOSBIOSVersion
        $biosSerial = $bios.SerialNumber

        if (($biosVersion -and $biosVersion -like '*Hyper-V*') -or
            ($biosSerial -and $biosSerial -like '*VRTUAL*')) {
            Write-vSEALLog -Message "Detected Hyper-V via BIOS information" -Level 'VERBOSE'
            $result.IsHyperV = $true
            $result.Hypervisor = 'Hyper-V'
            return $result
        }
    }
    catch {
        Write-vSEALLog -Message "Failed to query Win32_BIOS for Hyper-V detection: $_" -Level 'VERBOSE'
    }

    # No hypervisor detected - bare metal or unknown
    Write-vSEALLog -Message "No hypervisor detected - assuming bare metal or unknown platform" -Level 'VERBOSE'
    return $result
}
