Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Virtualization

    ''' <summary>
    ''' Result of the virtualization consumer diagnostics proof.
    ''' </summary>
    Friend NotInheritable Class MASVirtualizationConsumerDiagnosticsReport

        Private ReadOnly _requiredDiagnosticContexts As ReadOnlyCollection(Of String)
        Private ReadOnly _publishedDiagnosticContexts As ReadOnlyCollection(Of String)
        Private ReadOnly _requiredDiagnosticCodes As ReadOnlyCollection(Of String)
        Private ReadOnly _publishedDiagnosticCodes As ReadOnlyCollection(Of String)

        Friend Sub New(requiredDiagnosticContexts As IEnumerable(Of String),
                       publishedDiagnosticContexts As IEnumerable(Of String),
                       requiredDiagnosticCodes As IEnumerable(Of String),
                       publishedDiagnosticCodes As IEnumerable(Of String),
                       strictModeThrowsOnSwallowedFault As Boolean,
                       hasRenderFallbackContext As Boolean,
                       hasInputBoundaryContext As Boolean,
                       structuredFaultReport As MASVirtualizationConsumerFaultDiagnosticReport)
            _requiredDiagnosticContexts = New ReadOnlyCollection(Of String)(NormalizeDistinct(requiredDiagnosticContexts))
            _publishedDiagnosticContexts = New ReadOnlyCollection(Of String)(NormalizeDistinct(publishedDiagnosticContexts))
            _requiredDiagnosticCodes = New ReadOnlyCollection(Of String)(NormalizeDistinct(requiredDiagnosticCodes))
            _publishedDiagnosticCodes = New ReadOnlyCollection(Of String)(NormalizeDistinct(publishedDiagnosticCodes))
            Me.StrictModeThrowsOnSwallowedFault = strictModeThrowsOnSwallowedFault
            Me.HasRenderFallbackContext = hasRenderFallbackContext
            Me.HasInputBoundaryContext = hasInputBoundaryContext
            Me.StructuredFaultReport = structuredFaultReport
        End Sub

        Friend ReadOnly Property RequiredDiagnosticContexts As IReadOnlyList(Of String)
            Get
                Return _requiredDiagnosticContexts
            End Get
        End Property

        Friend ReadOnly Property PublishedDiagnosticContexts As IReadOnlyList(Of String)
            Get
                Return _publishedDiagnosticContexts
            End Get
        End Property

        Friend ReadOnly Property RequiredDiagnosticCodes As IReadOnlyList(Of String)
            Get
                Return _requiredDiagnosticCodes
            End Get
        End Property

        Friend ReadOnly Property PublishedDiagnosticCodes As IReadOnlyList(Of String)
            Get
                Return _publishedDiagnosticCodes
            End Get
        End Property

        Friend ReadOnly Property RequiredDiagnosticContextCount As Integer
            Get
                Return _requiredDiagnosticContexts.Count
            End Get
        End Property

        Friend ReadOnly Property PublishedDiagnosticContextCount As Integer
            Get
                Return _publishedDiagnosticContexts.Count
            End Get
        End Property

        Friend ReadOnly Property RequiredDiagnosticCodeCount As Integer
            Get
                Return _requiredDiagnosticCodes.Count
            End Get
        End Property

        Friend ReadOnly Property PublishedDiagnosticCodeCount As Integer
            Get
                Return _publishedDiagnosticCodes.Count
            End Get
        End Property

        Friend ReadOnly Property StrictModeThrowsOnSwallowedFault As Boolean
        Friend ReadOnly Property HasRenderFallbackContext As Boolean
        Friend ReadOnly Property HasInputBoundaryContext As Boolean
        Friend ReadOnly Property StructuredFaultReport As MASVirtualizationConsumerFaultDiagnosticReport

        Friend ReadOnly Property AllRequiredContextsPublished As Boolean
            Get
                If _requiredDiagnosticContexts.Count = 0 Then Return False

                For Each requiredContext As String In _requiredDiagnosticContexts
                    If Not _publishedDiagnosticContexts.Contains(requiredContext) Then
                        Return False
                    End If
                Next

                Return True
            End Get
        End Property

        Friend ReadOnly Property AllRequiredDiagnosticCodesPublished As Boolean
            Get
                If _requiredDiagnosticCodes.Count = 0 Then Return False

                For Each requiredCode As String In _requiredDiagnosticCodes
                    If Not _publishedDiagnosticCodes.Contains(requiredCode) Then
                        Return False
                    End If
                Next

                Return True
            End Get
        End Property

        Friend ReadOnly Property HasStructuredFaultReport As Boolean
            Get
                Return StructuredFaultReport IsNot Nothing AndAlso StructuredFaultReport.HasFaults
            End Get
        End Property

        Friend ReadOnly Property IsReady As Boolean
            Get
                Return StrictModeThrowsOnSwallowedFault AndAlso
                       HasRenderFallbackContext AndAlso
                       HasInputBoundaryContext AndAlso
                       AllRequiredContextsPublished AndAlso
                       AllRequiredDiagnosticCodesPublished AndAlso
                       HasStructuredFaultReport
            End Get
        End Property

        Private Shared Function NormalizeDistinct(values As IEnumerable(Of String)) As List(Of String)
            Dim result As New List(Of String)()
            If values Is Nothing Then Return result

            For Each value As String In values
                Dim normalized As String = If(value, String.Empty).Trim()
                If normalized.Length > 0 AndAlso Not result.Contains(normalized) Then
                    result.Add(normalized)
                End If
            Next

            Return result
        End Function

    End Class

End Namespace
