Modules/businessdev.ALbuild.RuntimePackages/Private/ConvertTo-BcRuntimeSummaryMarkdown.ps1

function ConvertTo-BcRuntimeSummaryMarkdown {
    <#
    .SYNOPSIS
        Renders the app x platform-version result matrix as Markdown for the stage summary.
 
    .DESCRIPTION
        The Tests tab answers "what failed?". This answers the question a release actually starts with -
        "what is still missing?" - by showing every app against every platform version in the run at
        once. Uploaded with '##vso[task.uploadsummary]' it becomes a tab on the stage, so the state of a
        catalogue-wide run is one glance rather than a log trawl.
 
        Columns are platform versions, newest first, matching the order the factory builds them in.
 
    .PARAMETER Result
        Per-version results with PlatformVersion and Products[] (Name, Status).
 
    .PARAMETER Title
        Heading for the summary.
 
    .OUTPUTS
        System.String - Markdown.
    #>

    [CmdletBinding()]
    [OutputType([string])]
    param(
        [Parameter(Mandatory)] [AllowEmptyCollection()] [object[]] $Result,
        [string] $Title = 'Runtime packages'
    )

    $symbol = @{ Succeeded = ':white_check_mark:'; Failed = ':x:'; Skipped = ':heavy_minus_sign:' }

    $versions = @($Result | ForEach-Object { "$($_.PlatformVersion)" })
    # Union of every app seen, in first-seen order - which is dependency order, because that is how the
    # worker processes them.
    $apps = [System.Collections.Generic.List[string]]::new()
    foreach ($v in @($Result)) {
        foreach ($p in @(Get-BcRuntimeProperty -InputObject $v -Name 'Products' -Default @())) {
            if (-not $apps.Contains("$($p.Name)")) { $apps.Add("$($p.Name)") }
        }
    }

    $sb = [System.Text.StringBuilder]::new()
    [void]$sb.AppendLine("## $Title")
    [void]$sb.AppendLine()

    if ($versions.Count -eq 0 -or $apps.Count -eq 0) {
        [void]$sb.AppendLine('Nothing to build - every planned runtime package already exists.')
        return $sb.ToString()
    }

    $total = 0; $failed = 0; $skipped = 0
    foreach ($v in @($Result)) {
        foreach ($p in @(Get-BcRuntimeProperty -InputObject $v -Name 'Products' -Default @())) {
            $total++
            if ($p.Status -eq 'Failed') { $failed++ }
            elseif ($p.Status -eq 'Skipped') { $skipped++ }
        }
    }
    [void]$sb.AppendLine("**$($total - $failed - $skipped) built**, **$failed failed**, **$skipped skipped** across $($versions.Count) platform version(s).")
    [void]$sb.AppendLine()

    [void]$sb.AppendLine("| App | $($versions -join ' | ') |")
    [void]$sb.AppendLine("|---|$(('---|' * $versions.Count))")

    foreach ($app in $apps) {
        $cells = foreach ($v in @($Result)) {
            $p = @(Get-BcRuntimeProperty -InputObject $v -Name 'Products' -Default @()) | Where-Object { "$($_.Name)" -eq $app } | Select-Object -First 1
            # No cell at all means the app was not applicable to that platform version (below its
            # app.json 'application' minimum) - deliberately distinct from 'skipped'.
            if ($p) { $symbol[$p.Status] } else { '·' }
        }
        [void]$sb.AppendLine("| $app | $(@($cells) -join ' | ') |")
    }

    return $sb.ToString()
}