Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Virtualization

    ''' <summary>
    ''' Report produced by MASLargeDataWindowingGate. It is intentionally internal and records
    ''' whether every cataloged large-data surface is either covered by the shared virtualization
    ''' behavior proof or by its own official bounded-window proof.
    ''' </summary>
    Friend NotInheritable Class MASLargeDataWindowingReport
        Private ReadOnly _bindings As IReadOnlyList(Of MASLargeDataWindowingBinding)
        Private ReadOnly _findings As IReadOnlyList(Of MASVirtualizationReadinessFinding)
        Private ReadOnly _provedSurfaceIds As IReadOnlyList(Of String)

        Friend Sub New(bindings As IEnumerable(Of MASLargeDataWindowingBinding),
                       findings As IEnumerable(Of MASVirtualizationReadinessFinding),
                       provedSurfaceIds As IEnumerable(Of String))
            _bindings = New ReadOnlyCollection(Of MASLargeDataWindowingBinding)(If(bindings, Enumerable.Empty(Of MASLargeDataWindowingBinding)()).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())
            _provedSurfaceIds = New ReadOnlyCollection(Of String)(NormalizeIds(provedSurfaceIds))
        End Sub

        Friend ReadOnly Property Bindings As IReadOnlyList(Of MASLargeDataWindowingBinding)
            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 ProvedSurfaceIds As IReadOnlyList(Of String)
            Get
                Return _provedSurfaceIds
            End Get
        End Property

        Friend ReadOnly Property ProvedSurfaceCount As Integer
            Get
                Return _provedSurfaceIds.Count
            End Get
        End Property

        Friend ReadOnly Property SharedControllerSurfaceCount As Integer
            Get
                Return Global.System.Linq.Enumerable.Count(_bindings, Function(binding) binding.IsSharedControllerSurface)
            End Get
        End Property

        Friend ReadOnly Property DomainSpecificWindowingSurfaceCount As Integer
            Get
                Return Global.System.Linq.Enumerable.Count(_bindings, Function(binding) binding.IsDomainSpecificWindowingSurface)
            End Get
        End Property

        Friend ReadOnly Property ProvedSharedControllerSurfaceCount As Integer
            Get
                Return Global.System.Linq.Enumerable.Count(_bindings, Function(binding) binding.IsSharedControllerSurface AndAlso Global.System.Linq.Enumerable.Contains(_provedSurfaceIds, binding.Id))
            End Get
        End Property

        Friend ReadOnly Property ProvedDomainSpecificWindowingSurfaceCount As Integer
            Get
                Return Global.System.Linq.Enumerable.Count(_bindings, Function(binding) binding.IsDomainSpecificWindowingSurface AndAlso Global.System.Linq.Enumerable.Contains(_provedSurfaceIds, binding.Id))
            End Get
        End Property

        Friend ReadOnly Property IsReady As Boolean
            Get
                Return _bindings.Count > 0 AndAlso
                       _provedSurfaceIds.Count = _bindings.Count 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
