param(
    [switch]$SkipYtDlpUpdate,
    [string]$ReportPath
)

$ErrorActionPreference = 'Stop'

$root = Split-Path -Parent $MyInvocation.MyCommand.Path
$encoders = Join-Path $root 'encoders'

if (-not $ReportPath) {
    $stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
    $misc = 'E:\Software\Misc'
    if (-not (Test-Path -LiteralPath $misc)) {
        $misc = $root
    }
    $ReportPath = Join-Path $misc "SendTo-encoder-update-check-$stamp.txt"
}

function Get-FirstLine {
    param([scriptblock]$Command)
    try {
        $output = & $Command 2>&1
        return ($output | Where-Object { $_ -and "$_".Trim() } | Select-Object -First 1).ToString()
    }
    catch {
        return "ERROR: $($_.Exception.Message)"
    }
}

function Get-Json {
    param([Parameter(Mandatory)][string]$Uri)
    Invoke-RestMethod -Uri $Uri -UseBasicParsing -Headers @{ 'User-Agent' = 'SendTo-release-check' }
}

function Add-Result {
    param(
        [Parameter(Mandatory)][string]$Name,
        [Parameter(Mandatory)][string]$Local,
        [Parameter(Mandatory)][string]$Latest,
        [Parameter(Mandatory)][string]$Status,
        [string]$Source
    )

    [pscustomobject]@{
        Name = $Name
        Local = $Local
        Latest = $Latest
        Status = $Status
        Source = $Source
    }
}

$results = New-Object System.Collections.Generic.List[object]

$ytDlp = Join-Path $encoders 'yt-dlp.exe'
if (Test-Path -LiteralPath $ytDlp) {
    if (-not $SkipYtDlpUpdate) {
        & $ytDlp -U | Out-Host
    }

    $localYtDlp = Get-FirstLine { & $ytDlp --version }
    $latestYtDlp = (Get-Json 'https://api.github.com/repos/yt-dlp/yt-dlp/releases/latest').tag_name
    $results.Add((Add-Result 'yt-dlp' $localYtDlp $latestYtDlp ($(if ($localYtDlp -eq $latestYtDlp) { 'Current' } else { 'Review' }) ) 'https://github.com/yt-dlp/yt-dlp/releases/latest'))
}

$ffmpeg = Join-Path $encoders 'ffmpeg.exe'
if (Test-Path -LiteralPath $ffmpeg) {
    $ffLine = Get-FirstLine { & $ffmpeg -hide_banner -version }
    $localFfmpeg = if ($ffLine -match 'ffmpeg version\s+([^\s]+)') { $Matches[1] } else { $ffLine }
    $latestFfmpeg = (Invoke-WebRequest -Uri 'https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full.7z.ver' -UseBasicParsing).Content
    if ($latestFfmpeg -is [byte[]]) {
        $latestFfmpeg = [Text.Encoding]::UTF8.GetString($latestFfmpeg)
    }
    $latestFfmpeg = $latestFfmpeg.Trim()
    $status = if ($localFfmpeg.StartsWith($latestFfmpeg)) { 'Current' } else { 'Review' }
    $results.Add((Add-Result 'ffmpeg full build' $localFfmpeg $latestFfmpeg $status 'https://www.gyan.dev/ffmpeg/builds/'))
}

$flac = Join-Path $encoders 'flac.exe'
if (Test-Path -LiteralPath $flac) {
    $flacLine = Get-FirstLine { & $flac --version }
    $localFlac = if ($flacLine -match 'flac\s+(.+)$') { $Matches[1] } else { $flacLine }
    $latestFlac = (Get-Json 'https://api.github.com/repos/xiph/flac/releases/latest').tag_name.TrimStart('v')
    $results.Add((Add-Result 'FLAC' $localFlac $latestFlac ($(if ($localFlac -eq $latestFlac) { 'Current' } else { 'Review' }) ) 'https://github.com/xiph/flac/releases/latest'))
}

$lame = Join-Path $encoders 'lame.exe'
if (Test-Path -LiteralPath $lame) {
    $lameLine = Get-FirstLine { & $lame --version }
    $localLame = if ($lameLine -match 'version\s+([0-9.]+)') { $Matches[1] } else { $lameLine }
    $results.Add((Add-Result 'LAME' $localLame '3.100 official stable' ($(if ($localLame -eq '3.100') { 'Current' } else { 'Review' }) ) 'https://lame.sourceforge.io/ / RareWares manual check'))
}

$opusenc = Join-Path $encoders 'opusenc.exe'
if (Test-Path -LiteralPath $opusenc) {
    $opusLine = Get-FirstLine { & $opusenc --version }
    $localOpus = if ($opusLine -match 'opus-tools\s+([^\s]+)') { $Matches[1] } else { $opusLine }
    $results.Add((Add-Result 'opus-tools' $localOpus '0.2 official tools' ($(if ($localOpus -eq '0.2') { 'Current' } else { 'Review' }) ) 'https://opus-codec.org/downloads/'))
}

$oggenc = Join-Path $encoders 'oggenc2.exe'
if (Test-Path -LiteralPath $oggenc) {
    $oggLine = Get-FirstLine { & $oggenc --version }
    $results.Add((Add-Result 'oggenc2' $oggLine 'Manual check' 'Manual' 'https://www.rarewares.org/ogg-oggenc.php'))
}

$vgm = Join-Path $encoders 'vgmstream-cli.exe'
if (Test-Path -LiteralPath $vgm) {
    $latestVgm = (Get-Json 'https://api.github.com/repos/vgmstream/vgmstream/releases/latest').tag_name
    $vgmLine = Get-FirstLine { & $vgm -h }
    $localVgm = if ($vgmLine -match 'r\d+') { $Matches[0] } else { $vgmLine }
    $results.Add((Add-Result 'vgmstream-cli' $localVgm $latestVgm ($(if ($localVgm -eq $latestVgm) { 'Current' } else { 'Review' }) ) 'https://github.com/vgmstream/vgmstream/releases/latest'))
}

$lines = @()
$lines += "SendTo bundled encoder update check"
$lines += "Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
$lines += ""
$lines += ($results | Format-Table -AutoSize | Out-String).TrimEnd()
$lines += ""
$lines += "Statuses:"
$lines += "Current = local version appears to match latest known release."
$lines += "Review = a newer version may exist or the check cannot compare automatically."
$lines += "Manual = inspect source manually before changing the bundled binary."

$lines | Set-Content -LiteralPath $ReportPath -Encoding UTF8
$results | Format-Table -AutoSize
Write-Host ""
Write-Host "Report written to $ReportPath"
