Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Certification

    ''' <summary>
    ''' Immutable aggregate for component-to-quality-evidence coverage.
    ''' </summary>
    Friend NotInheritable Class MASQualityComponentCoverageReport
        Private ReadOnly _entries As IReadOnlyList(Of MASQualityComponentCoverageEntry)

        Friend Sub New(entries As IEnumerable(Of MASQualityComponentCoverageEntry))
            Dim normalized As New List(Of MASQualityComponentCoverageEntry)()
            If entries IsNot Nothing Then
                For Each entry As MASQualityComponentCoverageEntry In entries
                    If entry IsNot Nothing Then normalized.Add(entry)
                Next
            End If

            _entries = New ReadOnlyCollection(Of MASQualityComponentCoverageEntry)(normalized)
        End Sub

        Friend ReadOnly Property Entries As IReadOnlyList(Of MASQualityComponentCoverageEntry)
            Get
                Return _entries
            End Get
        End Property

        Friend ReadOnly Property ComponentCount As Integer
            Get
                Return _entries.Count
            End Get
        End Property

        Friend ReadOnly Property BlockingGapCount As Integer
            Get
                Dim count As Integer = 0
                For Each entry As MASQualityComponentCoverageEntry In _entries
                    If entry Is Nothing OrElse entry.HasBlockingGap Then count += 1
                Next
                Return count
            End Get
        End Property

        Friend ReadOnly Property DirectRenderScenarioCount As Integer
            Get
                Return CountKind(MASQualityComponentCoverageKind.DirectRenderScenario)
            End Get
        End Property

        Friend ReadOnly Property FamilyRenderScenarioCount As Integer
            Get
                Return CountKind(MASQualityComponentCoverageKind.FamilyRenderScenario)
            End Get
        End Property

        Friend ReadOnly Property ContractProofCount As Integer
            Get
                Return CountKind(MASQualityComponentCoverageKind.AtomicContractProof) +
                       CountKind(MASQualityComponentCoverageKind.SizeLayoutContractProof) +
                       CountKind(MASQualityComponentCoverageKind.SurfaceMaterialProof) +
                       CountKind(MASQualityComponentCoverageKind.InteractionStateProof) +
                       CountKind(MASQualityComponentCoverageKind.SystemInventoryProof)
            End Get
        End Property

        Friend ReadOnly Property HasBlockingCoverageGaps As Boolean
            Get
                Return BlockingGapCount > 0
            End Get
        End Property

        Friend ReadOnly Property Summary As String
            Get
                Return ComponentCount.ToString(CultureInfo.InvariantCulture) &
                       " registered component descriptor(s), " &
                       DirectRenderScenarioCount.ToString(CultureInfo.InvariantCulture) &
                       " direct render scenario coverage, " &
                       FamilyRenderScenarioCount.ToString(CultureInfo.InvariantCulture) &
                       " family render scenario coverage, " &
                       ContractProofCount.ToString(CultureInfo.InvariantCulture) &
                       " contract/system proof coverage, " &
                       BlockingGapCount.ToString(CultureInfo.InvariantCulture) &
                       " blocking coverage gap(s)."
            End Get
        End Property

        Friend Function CreateBlockingGapDetails(maxCount As Integer) As IReadOnlyList(Of String)
            Dim details As New List(Of String)()
            Dim limit As Integer = Math.Max(1, maxCount)

            For Each entry As MASQualityComponentCoverageEntry In _entries
                If entry Is Nothing OrElse entry.HasBlockingGap Then
                    details.Add(If(entry Is Nothing, "<null coverage entry>", entry.ToString()))
                    If details.Count >= limit Then Exit For
                End If
            Next

            Return New ReadOnlyCollection(Of String)(details)
        End Function

        Friend Function CreateSampleDetails(maxCount As Integer) As IReadOnlyList(Of String)
            Dim details As New List(Of String)()
            Dim limit As Integer = Math.Max(1, maxCount)

            For Each entry As MASQualityComponentCoverageEntry In _entries
                If entry Is Nothing Then Continue For
                details.Add(entry.ToString())
                If details.Count >= limit Then Exit For
            Next

            Return New ReadOnlyCollection(Of String)(details)
        End Function

        Private Function CountKind(kind As MASQualityComponentCoverageKind) As Integer
            Dim count As Integer = 0
            For Each entry As MASQualityComponentCoverageEntry In _entries
                If entry IsNot Nothing AndAlso entry.CoverageKind = kind Then count += 1
            Next
            Return count
        End Function

    End Class

End Namespace
