#Requires -Version 7.4

function Get-vSEALAzurePlatformData {
    <#
    .SYNOPSIS
        Retrieves Azure Instance Metadata Service (IMDS) data if running on Azure.

    .DESCRIPTION
        Queries the Azure Instance Metadata Service (IMDS) endpoint to retrieve
        platform data about the current Azure VM. Returns $null if the machine
        is not running on Azure.

        The IMDS endpoint (169.254.169.254) is only accessible from within Azure VMs
        and is not routable from outside Azure.

    .PARAMETER TimeoutSeconds
        Maximum time to wait for IMDS response. Default is 2 seconds.
        Short timeout is appropriate since IMDS is a local link-local address.

    .PARAMETER ApiVersion
        Azure IMDS API version to use. Default is '2025-04-07'.

    .EXAMPLE
        Get-vSEALAzurePlatformData

        Returns Azure platform metadata if running on Azure, $null otherwise.

    .EXAMPLE
        $azure = Get-vSEALAzurePlatformData
        if ($azure) {
            Write-Host "Running on Azure VM: $($azure.compute.name)"
            Write-Host "Location: $($azure.compute.location)"
        } else {
            Write-Host "Not running on Azure"
        }

    .OUTPUTS
        [PSCustomObject]

    .NOTES
        Returns Azure IMDS metadata with compute and network information,
        or $null if not running on Azure.
        Azure IMDS documentation: https://docs.microsoft.com/azure/virtual-machines/windows/instance-metadata-service

    .LINK
        https://github.com/microsoft/azureimds
    #>
    [CmdletBinding()]
    [OutputType([PSCustomObject])]
    param(
        [Parameter()]
        [ValidateRange(1, 30)]
        [int]$TimeoutSeconds = 2,

        [Parameter()]
        [string]$ApiVersion = '2025-04-07'
    )

    begin {
        $imdsUri = "http://169.254.169.254/metadata/instance?api-version=$ApiVersion"
        $headers = @{ 'Metadata' = 'True' }
    }

    process {
        # Fail-fast: Quick TCP check before HTTP request (500ms timeout)
        Write-vSEALLog "Performing fail-fast TCP connectivity check to IMDS endpoint..." -Level 'VERBOSE'
        try {
            $tcpClient = [System.Net.Sockets.TcpClient]::new()
            $connectTask = $tcpClient.ConnectAsync('169.254.169.254', 80)
            $completed = $connectTask.Wait(500)  # 500ms TCP timeout

            if (-not $completed -or -not $tcpClient.Connected) {
                Write-vSEALLog "IMDS endpoint not reachable (TCP check failed) - not running on Azure" -Level 'VERBOSE'
                $tcpClient.Dispose()
                return $null
            }
            $tcpClient.Close()
            $tcpClient.Dispose()
            Write-vSEALLog "TCP connectivity confirmed, proceeding with HTTP request..." -Level 'VERBOSE'
        }
        catch {
            Write-vSEALLog "IMDS TCP check failed: $($_.Exception.Message) - not running on Azure" -Level 'VERBOSE'
            return $null
        }

        # Full HTTP request to get metadata
        try {
            Write-vSEALLog "Querying Azure IMDS endpoint: $imdsUri" -Level 'VERBOSE'

            $response = Invoke-RestMethod -Method Get `
                -Uri $imdsUri `
                -Headers $headers `
                -TimeoutSec $TimeoutSeconds `
                -NoProxy `
                -ErrorAction Stop

            Write-vSEALLog "Azure IMDS query successful - running on Azure" -Level 'VERBOSE'
            return $response
        }
        catch [System.Net.Http.HttpRequestException] {
            Write-vSEALLog "Azure IMDS not reachable (HttpRequestException): $($_.Exception.Message)" -Level 'VERBOSE'
            return $null
        }
        catch [System.Net.Sockets.SocketException] {
            Write-vSEALLog "Azure IMDS not reachable (SocketException): $($_.Exception.Message)" -Level 'VERBOSE'
            return $null
        }
        catch [System.Threading.Tasks.TaskCanceledException] {
            Write-vSEALLog "Azure IMDS request timed out - not running on Azure" -Level 'VERBOSE'
            return $null
        }
        catch {
            Write-vSEALLog "Azure IMDS query failed: $($_.Exception.Message)" -Level 'VERBOSE'
            return $null
        }
    }

}
