Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Verification

    ''' <summary>
    ''' Immutable report that compares RenderVerification targets/scenarios/capture scenes with component quality coverage.
    ''' </summary>
    Friend NotInheritable Class MASRenderVerificationCoverageReport
        Private ReadOnly _findings As IReadOnlyList(Of MASRenderVerificationCoverageFinding)

        Friend Sub New(targetCount As Integer,
                       scenarioCount As Integer,
                       registeredSceneCount As Integer,
                       componentCoverageCount As Integer,
                       findings As IEnumerable(Of MASRenderVerificationCoverageFinding))
            Me.TargetCount = Math.Max(0, targetCount)
            Me.ScenarioCount = Math.Max(0, scenarioCount)
            Me.RegisteredSceneCount = Math.Max(0, registeredSceneCount)
            Me.ComponentCoverageCount = Math.Max(0, componentCoverageCount)
            _findings = New ReadOnlyCollection(Of MASRenderVerificationCoverageFinding)(NormalizeFindings(findings))
        End Sub

        Friend ReadOnly Property TargetCount As Integer
        Friend ReadOnly Property ScenarioCount As Integer
        Friend ReadOnly Property RegisteredSceneCount As Integer
        Friend ReadOnly Property ComponentCoverageCount As Integer

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

        Friend ReadOnly Property FindingCount As Integer
            Get
                Return _findings.Count
            End Get
        End Property

        Friend ReadOnly Property IsComplete As Boolean
            Get
                Return FindingCount = 0
            End Get
        End Property

        Friend ReadOnly Property MissingCaptureSceneCount As Integer
            Get
                Return CountKind(MASRenderVerificationCoverageFindingKind.MissingCaptureScene)
            End Get
        End Property

        Friend ReadOnly Property OrphanCaptureSceneCount As Integer
            Get
                Return CountKind(MASRenderVerificationCoverageFindingKind.OrphanCaptureScene)
            End Get
        End Property

        Friend ReadOnly Property UnusedTargetCount As Integer
            Get
                Return CountKind(MASRenderVerificationCoverageFindingKind.UnusedTarget)
            End Get
        End Property

        Friend ReadOnly Property UnmappedComponentCoverageCount As Integer
            Get
                Return CountKind(MASRenderVerificationCoverageFindingKind.UnmappedComponentCoverage)
            End Get
        End Property

        Friend ReadOnly Property MissingCatalogScenarioCount As Integer
            Get
                Return CountKind(MASRenderVerificationCoverageFindingKind.MissingCatalogScenario)
            End Get
        End Property

        Friend ReadOnly Property Summary As String
            Get
                Return TargetCount.ToString(CultureInfo.InvariantCulture) & " target(s), " &
                       ScenarioCount.ToString(CultureInfo.InvariantCulture) & " catalog scenario(s), " &
                       RegisteredSceneCount.ToString(CultureInfo.InvariantCulture) & " registered capture scene(s), " &
                       ComponentCoverageCount.ToString(CultureInfo.InvariantCulture) & " component coverage row(s), " &
                       FindingCount.ToString(CultureInfo.InvariantCulture) & " render coverage graph finding(s)."
            End Get
        End Property

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

            For Each finding As MASRenderVerificationCoverageFinding In _findings
                If finding Is Nothing Then Continue For
                details.Add(finding.ToString())
                If details.Count >= limit Then Exit For
            Next

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

        Friend Function CreateSummaryDetails() As IReadOnlyList(Of String)
            Return New ReadOnlyCollection(Of String)(New List(Of String) From {
                "Missing capture scenes: " & MissingCaptureSceneCount.ToString(CultureInfo.InvariantCulture),
                "Orphan capture scenes: " & OrphanCaptureSceneCount.ToString(CultureInfo.InvariantCulture),
                "Unused targets: " & UnusedTargetCount.ToString(CultureInfo.InvariantCulture),
                "Unmapped component coverage rows: " & UnmappedComponentCoverageCount.ToString(CultureInfo.InvariantCulture),
                "Missing catalog scenario references: " & MissingCatalogScenarioCount.ToString(CultureInfo.InvariantCulture)
            })
        End Function

        Private Function CountKind(kind As MASRenderVerificationCoverageFindingKind) As Integer
            Dim count As Integer = 0
            For Each finding As MASRenderVerificationCoverageFinding In _findings
                If finding IsNot Nothing AndAlso finding.Kind = kind Then count += 1
            Next
            Return count
        End Function

        Private Shared Function NormalizeFindings(findings As IEnumerable(Of MASRenderVerificationCoverageFinding)) As List(Of MASRenderVerificationCoverageFinding)
            Dim result As New List(Of MASRenderVerificationCoverageFinding)()
            If findings Is Nothing Then Return result

            For Each finding As MASRenderVerificationCoverageFinding In findings
                If finding IsNot Nothing Then result.Add(finding)
            Next

            Return result
        End Function

    End Class

End Namespace
