Option Strict On
Option Explicit On

Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Linq

Namespace Nexamas.UI.Virtualization

    ''' <summary>
    ''' Aggregated commercial proof from a MASVirtualization benchmark run. The summary avoids machine-specific timing thresholds
    ''' while exposing stable facts that gates and diagnostics can use: scenario coverage, largest logical item set, bounded
    ''' realization ratio, sparse measurement proof, scroll-to-index proof, resize proof, and environment invalidation proof.
    ''' </summary>
    Friend NotInheritable Class MASVirtualizationBenchmarkSummary

        Private ReadOnly _results As IReadOnlyList(Of MASVirtualizationBenchmarkResult)

        Friend Sub New(results As IEnumerable(Of MASVirtualizationBenchmarkResult))
            Dim safeResults = If(results, Enumerable.Empty(Of MASVirtualizationBenchmarkResult)()).Where(Function(result) result IsNot Nothing).ToArray()
            _results = New ReadOnlyCollection(Of MASVirtualizationBenchmarkResult)(safeResults)

            ScenarioCount = safeResults.Length
            PassedScenarioCount = Global.System.Linq.Enumerable.Count(safeResults, Function(result) result.Passed)
            FailedScenarioCount = ScenarioCount - PassedScenarioCount
            TotalElapsedTicks = Global.System.Linq.Enumerable.Sum(safeResults, Function(result) result.ElapsedTicks)

            Dim maxLogical As Integer = 0
            Dim maxRealized As Integer = 0
            Dim maxRatio As Single = 0.0F
            For Each result In safeResults
                If result.Scenario IsNot Nothing Then
                    maxLogical = Math.Max(maxLogical, result.Scenario.ItemCount)
                End If

                maxRealized = Math.Max(maxRealized, result.RealizedCount)
                maxRatio = Math.Max(maxRatio, result.RealizedToLogicalItemRatio)
            Next

            MaxLogicalItemCount = maxLogical
            MaxRealizedItemCount = maxRealized
            MaxRealizedToLogicalRatio = maxRatio

            HasOneThousandItemProof = ContainsPassingScenario(safeResults, "items-1000")
            HasTenThousandItemProof = ContainsPassingScenario(safeResults, "items-10000")
            HasHundredThousandItemProof = ContainsPassingScenario(safeResults, "items-100000")
            HasFastScrollProof = ContainsPassingScenario(safeResults, "fast-scroll")
            HasScrollToIndexProof = ContainsPassingScenario(safeResults, "scroll-to-index")
            HasResizeProof = ContainsPassingScenario(safeResults, "resize")
            HasAutoInvalidationProof = safeResults.Any(Function(result) result.Passed AndAlso result.Diagnostics IsNot Nothing AndAlso result.Diagnostics.LastInvalidationReason <> MASVirtualizationInvalidationReason.None)
            HasVariableExtentProof = safeResults.Any(Function(result) result.Passed AndAlso result.Scenario IsNot Nothing AndAlso result.Scenario.ExtentStrategy = MASVirtualizationExtentStrategy.EstimatedWithMeasuredOverrides AndAlso result.MeasurementRevision > 0 AndAlso result.MeasurementCount > 0)
            HasBoundedRealizationProof = safeResults.Length > 0 AndAlso safeResults.All(Function(result) result.Passed AndAlso result.IsBoundedRealizationProof)
            HasSparseMeasurementProof = safeResults.Any(Function(result) result.Passed AndAlso result.MeasurementCount > 0 AndAlso result.MeasurementCount <= 8 AndAlso result.MeasurementRevision > 0)
        End Sub

        Friend ReadOnly Property Results As IReadOnlyList(Of MASVirtualizationBenchmarkResult)
            Get
                Return _results
            End Get
        End Property

        Friend ReadOnly Property ScenarioCount As Integer
        Friend ReadOnly Property PassedScenarioCount As Integer
        Friend ReadOnly Property FailedScenarioCount As Integer
        Friend ReadOnly Property MaxLogicalItemCount As Integer
        Friend ReadOnly Property MaxRealizedItemCount As Integer
        Friend ReadOnly Property MaxRealizedToLogicalRatio As Single
        Friend ReadOnly Property TotalElapsedTicks As Long
        Friend ReadOnly Property HasOneThousandItemProof As Boolean
        Friend ReadOnly Property HasTenThousandItemProof As Boolean
        Friend ReadOnly Property HasHundredThousandItemProof As Boolean
        Friend ReadOnly Property HasFastScrollProof As Boolean
        Friend ReadOnly Property HasScrollToIndexProof As Boolean
        Friend ReadOnly Property HasResizeProof As Boolean
        Friend ReadOnly Property HasAutoInvalidationProof As Boolean
        Friend ReadOnly Property HasVariableExtentProof As Boolean
        Friend ReadOnly Property HasBoundedRealizationProof As Boolean
        Friend ReadOnly Property HasSparseMeasurementProof As Boolean

        Friend ReadOnly Property IsCommercialProofReady As Boolean
            Get
                Return ScenarioCount >= 7 AndAlso
                       FailedScenarioCount = 0 AndAlso
                       MaxLogicalItemCount >= 100000 AndAlso
                       HasOneThousandItemProof AndAlso
                       HasTenThousandItemProof AndAlso
                       HasHundredThousandItemProof AndAlso
                       HasFastScrollProof AndAlso
                       HasScrollToIndexProof AndAlso
                       HasResizeProof AndAlso
                       HasAutoInvalidationProof AndAlso
                       HasVariableExtentProof AndAlso
                       HasBoundedRealizationProof AndAlso
                       HasSparseMeasurementProof
            End Get
        End Property

        Private Shared Function ContainsPassingScenario(results As IEnumerable(Of MASVirtualizationBenchmarkResult), scenarioId As String) As Boolean
            Dim safeId = If(scenarioId, String.Empty)
            Return If(results, Enumerable.Empty(Of MASVirtualizationBenchmarkResult)()).Any(Function(result) result IsNot Nothing AndAlso result.Passed AndAlso result.Scenario IsNot Nothing AndAlso String.Equals(result.Scenario.Id, safeId, Global.System.StringComparison.Ordinal))
        End Function

    End Class

End Namespace
