Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

$repoRoot = Split-Path -Parent $PSScriptRoot
$pluginsRoot = Join-Path $repoRoot "plugins"
$toolRoot = Join-Path $repoRoot ".tools"
$recoveryRoot = Join-Path $repoRoot ".recovery"
$extractRoot = Join-Path $recoveryRoot "extract"
$decompileRoot = Join-Path $recoveryRoot "decompiled"
$inventoryPath = Join-Path $recoveryRoot "inventory.csv"
$toolExe = Join-Path $toolRoot "ilspycmd.exe"

function Ensure-Directory([string]$Path) {
    if (-not (Test-Path -LiteralPath $Path)) {
        New-Item -ItemType Directory -Path $Path | Out-Null
    }
}

function Reset-Directory([string]$Path) {
    if (Test-Path -LiteralPath $Path) {
        Remove-Item -LiteralPath $Path -Recurse -Force
    }

    New-Item -ItemType Directory -Path $Path | Out-Null
}

function Get-RuntimeTarget([string]$DepsPath) {
    if (-not (Test-Path -LiteralPath $DepsPath)) {
        return $null
    }

    try {
        $deps = Get-Content -LiteralPath $DepsPath -Raw | ConvertFrom-Json
        return $deps.runtimeTarget.name
    }
    catch {
        return $null
    }
}

Ensure-Directory $toolRoot
Ensure-Directory $recoveryRoot
Ensure-Directory $extractRoot
Ensure-Directory $decompileRoot

if (-not (Test-Path -LiteralPath $toolExe)) {
    dotnet tool install --tool-path $toolRoot ilspycmd | Out-Host
}

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

Get-ChildItem -LiteralPath $pluginsRoot -Directory | Sort-Object Name | ForEach-Object {
    $pluginDir = $_
    $zipPath = Join-Path $pluginDir.FullName "latest.zip"

    if (-not (Test-Path -LiteralPath $zipPath)) {
        return
    }

    $extractPath = Join-Path $extractRoot $pluginDir.Name
    Reset-Directory $extractPath
    Expand-Archive -LiteralPath $zipPath -DestinationPath $extractPath -Force

    $dlls = Get-ChildItem -LiteralPath $extractPath -Filter "*.dll" -File

    foreach ($dll in $dlls) {
        $assemblyName = [System.IO.Path]::GetFileNameWithoutExtension($dll.Name)
        $projectPath = Join-Path $decompileRoot $assemblyName
        Reset-Directory $projectPath

        & $toolExe -p -o $projectPath $dll.FullName | Out-Host

        $depsPath = Join-Path $extractPath ($assemblyName + ".deps.json")
        $pdbPath = Join-Path $extractPath ($assemblyName + ".pdb")

        $inventory.Add([pscustomobject]@{
            PluginFolder = $pluginDir.Name
            AssemblyName = $assemblyName
            RuntimeTarget = Get-RuntimeTarget $depsPath
            ZipPath = $zipPath
            DllPath = $dll.FullName
            HasPdb = Test-Path -LiteralPath $pdbPath
            ExtractPath = $extractPath
            ProjectPath = $projectPath
        })
    }
}

$inventory |
    Sort-Object PluginFolder, AssemblyName |
    Export-Csv -LiteralPath $inventoryPath -NoTypeInformation

$inventory |
    Sort-Object PluginFolder, AssemblyName |
    Format-Table PluginFolder, AssemblyName, RuntimeTarget, HasPdb, ProjectPath
