<#
.SYNOPSIS
    RR3 Asset Downloader - Downloads game assets from EA's CDN while available

.DESCRIPTION
    Parses asset manifests and downloads files from EA's servers.
    Verifies MD5 hashes and organizes files for community server.

.PARAMETER ManifestFiles
    Specific manifest files to process (default: critical assets only)

.PARAMETER MaxParallelDownloads
    Maximum concurrent downloads (default: 5)

.PARAMETER TestMode
    Download first 10 assets only for testing
#>

param(
    [string[]]$ManifestFiles = @(
        "asset_list_base.txt",
        "asset_list_audio_base.txt",
        "asset_list_base_gui.txt"
    ),
    [int]$MaxParallelDownloads = 5,
    [switch]$TestMode
)

$ErrorActionPreference = "Continue"

# Configuration
$ManifestPath = "E:\rr3\RR3CommunityServer\RR3CommunityServer\Assets\manifests"
$DestinationPath = "E:\rr3\RR3CommunityServer\RR3CommunityServer\Assets\downloaded"
$EaCdnBaseUrl = "https://d1q35ni3zsr8wd.cloudfront.net"  # EA's actual CDN (CloudFront)
$LogFile = "E:\rr3\asset-download-log.txt"

# Statistics
$Global:Stats = @{
    Total = 0
    Downloaded = 0
    Skipped = 0
    Failed = 0
    BytesDownloaded = 0
}

# Initialize
Write-Host "═══════════════════════════════════════════════════════════" -ForegroundColor Cyan
Write-Host "   🎮 Real Racing 3 - Asset Preservation Downloader 💾" -ForegroundColor Cyan
Write-Host "═══════════════════════════════════════════════════════════" -ForegroundColor Cyan
Write-Host ""

if (!(Test-Path $DestinationPath)) {
    New-Item -ItemType Directory -Path $DestinationPath | Out-Null
    Write-Host "✓ Created download directory" -ForegroundColor Green
}

# Ensure log directory exists
$LogDir = Split-Path $LogFile -Parent
if (!(Test-Path $LogDir)) {
    New-Item -ItemType Directory -Path $LogDir | Out-Null
}

"=== RR3 Asset Download Started: $(Get-Date) ===" | Out-File $LogFile -Encoding utf8

function Get-MD5Hash {
    param([string]$FilePath)
    $md5 = [System.Security.Cryptography.MD5]::Create()
    $stream = [System.IO.File]::OpenRead($FilePath)
    $hash = $md5.ComputeHash($stream)
    $stream.Close()
    return [BitConverter]::ToString($hash).Replace("-", "").ToLower()
}

function Download-Asset {
    param(
        [string]$AssetPath,
        [string]$ExpectedMD5,
        [int]$CompressedSize,
        [int]$UncompressedSize
    )

    try {
        # Determine local save path
        $relativePath = $AssetPath.TrimStart('/')
        $localPath = Join-Path $DestinationPath $relativePath
        $localDir = Split-Path $localPath -Parent

        # Skip if already downloaded and hash matches
        if (Test-Path $localPath) {
            $actualMD5 = Get-MD5Hash $localPath
            if ($actualMD5 -eq $ExpectedMD5) {
                Write-Host "  ⏭️  SKIP: $AssetPath (already cached)" -ForegroundColor Gray
                $Global:Stats.Skipped++
                return $true
            } else {
                Write-Host "  🔄 RE-DOWNLOAD: $AssetPath (hash mismatch)" -ForegroundColor Yellow
            }
        }

        # Ensure directory exists
        if (!(Test-Path $localDir)) {
            New-Item -ItemType Directory -Path $localDir -Force | Out-Null
        }

        # Download from EA CDN
        $url = "$EaCdnBaseUrl$AssetPath"
        Write-Host "  ⬇️  Downloading: $AssetPath ($([math]::Round($CompressedSize/1KB, 2)) KB)" -ForegroundColor Cyan

        $webClient = New-Object System.Net.WebClient
        $webClient.Headers.Add("User-Agent", "RealRacing3/12.6.0")
        $webClient.DownloadFile($url, $localPath)
        $webClient.Dispose()

        # Verify MD5
        $actualMD5 = Get-MD5Hash $localPath
        if ($actualMD5 -eq $ExpectedMD5) {
            Write-Host "  ✅ SUCCESS: $AssetPath" -ForegroundColor Green
            $Global:Stats.Downloaded++
            $Global:Stats.BytesDownloaded += (Get-Item $localPath).Length
            "SUCCESS: $AssetPath" | Out-File $LogFile -Append -Encoding utf8
            return $true
        } else {
            Write-Host "  ❌ HASH MISMATCH: $AssetPath" -ForegroundColor Red
            Write-Host "     Expected: $ExpectedMD5" -ForegroundColor Red
            Write-Host "     Got:      $actualMD5" -ForegroundColor Red
            Remove-Item $localPath -Force
            $Global:Stats.Failed++
            "FAILED (hash): $AssetPath" | Out-File $LogFile -Append -Encoding utf8
            return $false
        }
    } catch {
        Write-Host "  ❌ DOWNLOAD ERROR: $AssetPath" -ForegroundColor Red
        Write-Host "     Error: $($_.Exception.Message)" -ForegroundColor Red
        $Global:Stats.Failed++
        "FAILED (error): $AssetPath - $($_.Exception.Message)" | Out-File $LogFile -Append -Encoding utf8
        return $false
    }
}

# Process each manifest
foreach ($manifestFile in $ManifestFiles) {
    $manifestPath = Join-Path $ManifestPath $manifestFile

    if (!(Test-Path $manifestPath)) {
        Write-Host "⚠️  Manifest not found: $manifestFile" -ForegroundColor Yellow
        continue
    }

    Write-Host ""
    Write-Host "📋 Processing: $manifestFile" -ForegroundColor Cyan
    Write-Host "═══════════════════════════════════════════════════════════" -ForegroundColor Cyan

    $lines = Get-Content $manifestPath

    if ($TestMode) {
        Write-Host "🧪 TEST MODE: Downloading first 10 assets only" -ForegroundColor Yellow
        $lines = $lines | Select-Object -First 10
    }

    $Global:Stats.Total += $lines.Count

    # Download assets
    $index = 0
    foreach ($line in $lines) {
        $index++
        $parts = $line -split "`t"

        if ($parts.Count -ne 4) {
            Write-Host "  ⚠️  Invalid line format: $line" -ForegroundColor Yellow
            continue
        }

        $assetPath = $parts[0]
        $md5 = $parts[1]
        $compressedSize = [int]$parts[2]
        $uncompressedSize = [int]$parts[3]

        Write-Host ""
        Write-Host "[$index/$($lines.Count)] Asset: $assetPath" -ForegroundColor White

        Download-Asset -AssetPath $assetPath -ExpectedMD5 $md5 -CompressedSize $compressedSize -UncompressedSize $uncompressedSize

        # Respectful delay (don't hammer EA's servers)
        Start-Sleep -Milliseconds 500
    }
}

# Summary
Write-Host ""
Write-Host "═══════════════════════════════════════════════════════════" -ForegroundColor Cyan
Write-Host "   📊 DOWNLOAD SUMMARY" -ForegroundColor Cyan
Write-Host "═══════════════════════════════════════════════════════════" -ForegroundColor Cyan
Write-Host ""
Write-Host "Total Assets:     $($Global:Stats.Total)" -ForegroundColor White
Write-Host "Downloaded:       $($Global:Stats.Downloaded)" -ForegroundColor Green
Write-Host "Skipped (cached): $($Global:Stats.Skipped)" -ForegroundColor Gray
Write-Host "Failed:           $($Global:Stats.Failed)" -ForegroundColor Red
Write-Host "Data Downloaded:  $([math]::Round($Global:Stats.BytesDownloaded/1MB, 2)) MB" -ForegroundColor Cyan
Write-Host ""

if ($Global:Stats.Failed -gt 0) {
    Write-Host "⚠️  Some downloads failed. Check log: $LogFile" -ForegroundColor Yellow
} else {
    Write-Host "✅ All downloads completed successfully!" -ForegroundColor Green
}

Write-Host ""
Write-Host "Log saved to: $LogFile" -ForegroundColor Gray
Write-Host "Assets saved to: $DestinationPath" -ForegroundColor Gray

"=== Download Completed: $(Get-Date) ===" | Out-File $LogFile -Append -Encoding utf8
"Total: $($Global:Stats.Total), Downloaded: $($Global:Stats.Downloaded), Skipped: $($Global:Stats.Skipped), Failed: $($Global:Stats.Failed)" | Out-File $LogFile -Append -Encoding utf8
