Private/Utils/Get-AzAdvertizerCsv.ps1

function Get-AzAdvertizerCsv {
    <#
    .SYNOPSIS
        Download and cache AzAdvertizer policy CSV with automatic refresh.
     
    .DESCRIPTION
        Downloads Azure Policy baseline CSV from AzAdvertizer with intelligent caching.
        Uses cached version if available and not expired, otherwise downloads fresh copy.
     
    .PARAMETER Url
        URL to download the CSV from. Defaults to AzAdvertizer's official URL.
     
    .PARAMETER CachePath
        Local file path for caching. Auto-detects appropriate temp location if not specified.
     
    .PARAMETER MaxAgeHours
        Maximum age of cached file in hours before refresh. Default: 24.
     
    .EXAMPLE
        $csvPath = Get-AzAdvertizerCsv
        Returns path to cached/downloaded CSV file
     
    .OUTPUTS
        String - Path to the CSV file (cached or freshly downloaded)
    #>

    [CmdletBinding()]
    param(
        [string]$Url,
        [string]$CachePath,  
        [int]$MaxAgeHours = 24
    )

    # Auto-detect cache path if not specified
    if ([string]::IsNullOrWhiteSpace($CachePath)) {
        if ($env:GITHUB_ACTIONS) {
            # GitHub Actions environment
            $CachePath = "C:\Temp\azpolicyadvertizer-cache.csv"
        }
        elseif (Test-Path "C:\") {
            # Windows environment
            $CachePath = "C:\Temp\azpolicyadvertizer-cache.csv"
        }
        else {
            # Unix-like environment
            $CachePath = "/tmp/azpolicyadvertizer-cache.csv"
        }
        
        # Ensure cache directory exists
        $cacheDir = Split-Path $CachePath -Parent
        if (-not (Test-Path $cacheDir)) {
            New-Item -ItemType Directory -Path $cacheDir -Force | Out-Null
            Write-Host "📁 Created cache directory: $cacheDir" -ForegroundColor Green
        }
        
        Write-Host "📍 Cache location: $CachePath" -ForegroundColor DarkGray
    }

    # Default URL
    if ([string]::IsNullOrWhiteSpace($Url)) {
        $Url = "https://www.azadvertizer.net/azpolicyadvertizer-comma.csv"
    }

    $needsDownload = $true

    # Check cache validity
    if (Test-Path $CachePath) {
        try {
            $file = Get-Item -Path $CachePath -ErrorAction Stop
            $fileAgeHours = ((Get-Date) - $file.LastWriteTime).TotalHours

            if ($fileAgeHours -lt $MaxAgeHours) {
                try {
                    $csv = Import-Csv -Path $CachePath -ErrorAction Stop
                    $cachedCount = if ($csv -is [array]) { $csv.Count } else { 1 }
                    Write-Host ("✅ Using cached AzAdvertizer CSV (age: {0:N1}h) - {1} entries" -f $fileAgeHours, $cachedCount) -ForegroundColor Green
                } catch {
                    Write-Warning ("⚠️ Cache exists but failed to parse CSV: {0}" -f $_.Exception.Message)
                }

                $needsDownload = $false
            } else {
                Write-Host ("⚠️ Cached CSV is {0:N1}h old (max: {1}h), will refresh..." -f $fileAgeHours, $MaxAgeHours) -ForegroundColor Yellow
            }
        } catch {
            Write-Warning ("Failed to inspect cache file: {0}" -f $_.Exception.Message)
        }
    }

    # Download if needed
    if ($needsDownload) {
        try {
            Write-Host ("📥 Downloading AzAdvertizer CSV from: {0}" -f $Url) -ForegroundColor Cyan
            
            # Ensure cache directory exists
            $cacheDir = Split-Path $CachePath -Parent
            if (-not (Test-Path $cacheDir)) {
                New-Item -ItemType Directory -Path $cacheDir -Force | Out-Null
            }
            
            Invoke-WebRequest -Uri $Url -OutFile $CachePath -TimeoutSec 30 -ErrorAction Stop
            Write-Host ("✅ Downloaded and cached: {0}" -f $CachePath) -ForegroundColor Green

            try {
                $csv = Import-Csv -Path $CachePath -ErrorAction Stop
                $count = if ($csv -is [array]) { $csv.Count } else { 1 }
                Write-Host (" └─ Entries downloaded: {0}" -f $count) -ForegroundColor DarkCyan
            } catch {
                Write-Warning ("Downloaded file saved but failed to parse as CSV: {0}" -f $_.Exception.Message)
            }
        } catch {
            Write-Warning ("Download failed: {0}" -f $_.Exception.Message)
            if (-not (Test-Path $CachePath)) {
                throw "No cached CSV available and download failed from: $Url"
            }
            Write-Warning ("Using stale cached CSV: {0}" -f $CachePath)
        }
    }

    return $CachePath
}