# Invoke-FilteredReportIP.ps1
# Reports this bay's GE corp IP to the GE Tines webhook with a tight
# subnet filter so PXE LAN (10.9.100.x) or any other 10.x stray address
# never leaks. Mirrors the payload shape of GE's Intune-deployed
# ReportIPAddresses_v2.ps1 so the receiving Tines workflow accepts it.
#
# WHY:
#   GE's signed Report IP script filters Get-NetIPAddress with
#   $_.StartsWith("10.") - too broad for WJ where PXE LAN is also 10.x.
#   Calling our own POST with a narrow filter guarantees the webhook
#   only ever sees the bay's AESFMA corp 10.x address.
#
# ALLOWED RANGES (WJ-specific - update if site moves to a new VLAN):
#   10.134.48.0/23   (10.134.48.0 - 10.134.49.255)
#   10.48.249.0/26   (10.48.249.0 - 10.48.249.63)

param(
    [switch]$Force,
    [int]$MaxAttempts = 6,
    [int]$RetrySeconds = 10
)

$ErrorActionPreference = 'Continue'
$logFile = 'C:\Logs\FilteredReportIP.log'
New-Item -ItemType Directory -Path 'C:\Logs' -Force -ErrorAction SilentlyContinue | Out-Null

function Log([string]$msg) {
    $ts = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
    "$ts $msg" | Tee-Object -FilePath $logFile -Append
}

# Allowed ranges (CIDR -> first IP int + prefix bits)
$allowedRanges = @(
    @{ Network = '10.134.48.0';  PrefixLen = 23 },
    @{ Network = '10.48.249.0';  PrefixLen = 26 }
)

function ConvertTo-Uint32($ip) {
    $bytes = ([System.Net.IPAddress]::Parse($ip)).GetAddressBytes()
    [Array]::Reverse($bytes)
    return [BitConverter]::ToUInt32($bytes, 0)
}

function Test-InAllowedRange([string]$ip) {
    try {
        $ipInt = ConvertTo-Uint32 $ip
        foreach ($r in $allowedRanges) {
            $netInt  = ConvertTo-Uint32 $r.Network
            $mask    = [uint32]([math]::Pow(2, 32) - [math]::Pow(2, 32 - $r.PrefixLen))
            if (($ipInt -band $mask) -eq ($netInt -band $mask)) { return $true }
        }
    } catch {}
    return $false
}

Log "=== Filtered Report IP fire ==="
$allIPs = Get-NetIPAddress -AddressFamily IPv4 -ErrorAction SilentlyContinue |
          Where-Object { $_.IPAddress -notmatch '^169\.254' -and $_.IPAddress -ne '127.0.0.1' } |
          Select-Object -ExpandProperty IPAddress
Log "All IPv4 addresses on this bay: $($allIPs -join ', ')"

$match = @($allIPs | Where-Object { Test-InAllowedRange $_ })
if ($match.Count -eq 0) {
    Log "No IP in allowed ranges (10.134.48.0/23 or 10.48.249.0/26). Not POSTing."
    exit 2
}
$reportIP = $match[0]
Log "Reporting IP: $reportIP"

$statusFile = "$env:ProgramData\GEA\FilteredReportIP\last-ip.txt"
$lastIP = ''
if (Test-Path $statusFile) { $lastIP = (Get-Content $statusFile -ErrorAction SilentlyContinue) -join '' }
if (-not $Force -and $lastIP -eq $reportIP) {
    Log "IP unchanged from last POST ($lastIP). Skipping."
    exit 0
}

$webhookUrl = 'https://tines.apps.geaerospace.com/webhook/aa891efac08bab3d077d9956ab6614d0/c687048cb0ee35c33760ad14cb9257eb'
$body = @{
    host         = $env:COMPUTERNAME
    fqdn         = "$env:COMPUTERNAME.device.geaerospace.net"
    IP           = $reportIP
    force_update = if ($Force) { 'True' } else { 'False' }
}

for ($i = 1; $i -le $MaxAttempts; $i++) {
    try {
        Log "POST attempt $i/$MaxAttempts ..."
        $resp = Invoke-WebRequest -Uri $webhookUrl -Method POST -Body $body -TimeoutSec 60 -UseBasicParsing -ErrorAction Stop
        Log "POST succeeded. StatusCode=$($resp.StatusCode) Content=$($resp.Content)"
        New-Item -ItemType Directory -Path (Split-Path $statusFile) -Force -ErrorAction SilentlyContinue | Out-Null
        Set-Content -Path $statusFile -Value $reportIP -Force
        exit 0
    } catch {
        Log "POST attempt $i failed: $_"
        if ($i -lt $MaxAttempts) { Start-Sleep -Seconds $RetrySeconds }
    }
}
Log "All $MaxAttempts attempts failed - giving up."
exit 1
