Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Virtualization

    ''' <summary>
    ''' Accessibility virtual-range proof report. It proves that each official virtualized consumer can navigate to an
    ''' off-screen logical item through the shared scroll bridge while keeping accessibility metadata tied to logical count,
    ''' not merely to currently realized visuals.
    ''' </summary>
    Friend NotInheritable Class MASVirtualizationAccessibleRangeReport
        Private ReadOnly _bindings As IReadOnlyList(Of MASVirtualizationAccessibleRangeBinding)
        Private ReadOnly _findings As IReadOnlyList(Of MASVirtualizationReadinessFinding)
        Private ReadOnly _provedConsumerIds As IReadOnlyList(Of String)

        Friend Sub New(bindings As IEnumerable(Of MASVirtualizationAccessibleRangeBinding),
                       findings As IEnumerable(Of MASVirtualizationReadinessFinding),
                       provedConsumerIds As IEnumerable(Of String))
            _bindings = New ReadOnlyCollection(Of MASVirtualizationAccessibleRangeBinding)(If(bindings, Enumerable.Empty(Of MASVirtualizationAccessibleRangeBinding)()).Where(Function(binding) binding IsNot Nothing).ToArray())
            _findings = New ReadOnlyCollection(Of MASVirtualizationReadinessFinding)(If(findings, Enumerable.Empty(Of MASVirtualizationReadinessFinding)()).Where(Function(finding) finding IsNot Nothing).ToArray())
            _provedConsumerIds = New ReadOnlyCollection(Of String)(NormalizeIds(provedConsumerIds))
        End Sub

        Friend ReadOnly Property Bindings As IReadOnlyList(Of MASVirtualizationAccessibleRangeBinding)
            Get
                Return _bindings
            End Get
        End Property

        Friend ReadOnly Property Findings As IReadOnlyList(Of MASVirtualizationReadinessFinding)
            Get
                Return _findings
            End Get
        End Property

        Friend ReadOnly Property ProvedConsumerIds As IReadOnlyList(Of String)
            Get
                Return _provedConsumerIds
            End Get
        End Property

        Friend ReadOnly Property AccessibleRangeSurfaceCount As Integer
            Get
                Return _bindings.Count
            End Get
        End Property

        Friend ReadOnly Property ProvedAccessibleRangeSurfaceCount As Integer
            Get
                Return _provedConsumerIds.Count
            End Get
        End Property

        Friend ReadOnly Property ActiveAccessibleRangeProofCount As Integer
            Get
                Return Global.System.Linq.Enumerable.Count(_bindings, Function(binding) binding IsNot Nothing AndAlso Not binding.IsComposed AndAlso Global.System.Linq.Enumerable.Contains(_provedConsumerIds, binding.ConsumerId))
            End Get
        End Property

        Friend ReadOnly Property ComposedAccessibleRangeProofCount As Integer
            Get
                Return Global.System.Linq.Enumerable.Count(_bindings, Function(binding) binding IsNot Nothing AndAlso binding.IsComposed AndAlso Global.System.Linq.Enumerable.Contains(_provedConsumerIds, binding.ConsumerId))
            End Get
        End Property

        Friend ReadOnly Property AllBindingsExposeLogicalPositionMetadata As Boolean
            Get
                Return _bindings.Count > 0 AndAlso _bindings.All(Function(binding) binding.ExposesLogicalPositionMetadata)
            End Get
        End Property

        Friend ReadOnly Property AllBindingsUseScrollToIndexBridge As Boolean
            Get
                Return _bindings.Count > 0 AndAlso _bindings.All(Function(binding) binding.UsesScrollToIndexBridge)
            End Get
        End Property

        Friend ReadOnly Property AllSnapshotsBoundedToRealizedRange As Boolean
            Get
                Return _bindings.Count > 0 AndAlso _bindings.All(Function(binding) binding.KeepsSnapshotBoundedToRealizedRange)
            End Get
        End Property

        Friend ReadOnly Property IsReady As Boolean
            Get
                Return _bindings.Count > 0 AndAlso
                       _provedConsumerIds.Count = _bindings.Count AndAlso
                       AllBindingsExposeLogicalPositionMetadata AndAlso
                       AllBindingsUseScrollToIndexBridge AndAlso
                       AllSnapshotsBoundedToRealizedRange AndAlso
                       Not _findings.Any(Function(finding) finding.Severity = MASVirtualizationFindingSeverity.Error)
            End Get
        End Property

        Private Shared Function NormalizeIds(ids As IEnumerable(Of String)) As String()
            Dim result As New List(Of String)()
            If ids Is Nothing Then Return result.ToArray()

            For Each rawId As String In ids
                Dim id As String = If(rawId, String.Empty).Trim()
                If id.Length = 0 Then Continue For
                If result.Contains(id) Then Continue For
                result.Add(id)
            Next

            Return result.ToArray()
        End Function
    End Class

End Namespace
