Option Strict On
Option Explicit On

Namespace Nexamas.UI.Rendering

    ''' <summary>
    ''' Aggregate Visual ownership report used by gates/readiness code to prove that
    ''' material, shadow, frame/chrome, effects, interaction, and component chrome
    ''' no longer share a retired Theme rendering owner.
    ''' </summary>
    Friend NotInheritable Class MASVisualOwnershipLockdownReport
        Friend ReadOnly Property Name As String
        Friend ReadOnly Property Entries As MASVisualOwnershipEntry()
        Friend ReadOnly Property EntryCount As Integer
        Friend ReadOnly Property ReadyAreaCount As Integer
        Friend ReadOnly Property SurfaceAlignmentReady As Boolean
        Friend ReadOnly Property PreservesCurrentVisuals As Boolean
        Friend ReadOnly Property ThemeRenderingBoundaryLocked As Boolean
        Friend ReadOnly Property BlocksParallelRoutes As Boolean
        Friend ReadOnly Property IsLockedDown As Boolean

        Friend Sub New(name As String,
                       entries As MASVisualOwnershipEntry(),
                       surfaceAlignmentReady As Boolean)
            Me.Name = Normalize(name, "Visual Ownership Lockdown")
            Me.Entries = If(entries, New MASVisualOwnershipEntry() {})
            Me.EntryCount = Me.Entries.Length
            Me.SurfaceAlignmentReady = surfaceAlignmentReady

            Dim ready As Integer = 0
            Dim preserves As Boolean = Me.EntryCount > 0
            Dim themeBoundary As Boolean = Me.EntryCount > 0
            Dim parallelRoutes As Boolean = Me.EntryCount > 0

            For Each entry As MASVisualOwnershipEntry In Me.Entries
                If entry Is Nothing Then
                    preserves = False
                    themeBoundary = False
                    parallelRoutes = False
                    Continue For
                End If

                If entry.IsReady Then ready += 1
                preserves = preserves AndAlso entry.PreservesCurrentVisuals
                themeBoundary = themeBoundary AndAlso entry.BlocksLegacyThemeRendering
                parallelRoutes = parallelRoutes AndAlso entry.BlocksParallelRoute
            Next

            Me.ReadyAreaCount = ready
            Me.PreservesCurrentVisuals = preserves
            Me.ThemeRenderingBoundaryLocked = themeBoundary
            Me.BlocksParallelRoutes = parallelRoutes
            Me.IsLockedDown = surfaceAlignmentReady AndAlso
                              Me.EntryCount = ExpectedAreaCount() AndAlso
                              ready = Me.EntryCount AndAlso
                              preserves AndAlso
                              themeBoundary AndAlso
                              parallelRoutes AndAlso
                              ContainsAllExpectedAreas()
        End Sub

        Friend Function Contains(area As MASVisualOwnershipArea) As Boolean
            For Each entry As MASVisualOwnershipEntry In Entries
                If entry IsNot Nothing AndAlso entry.Area = area Then Return True
            Next
            Return False
        End Function

        Private Function ContainsAllExpectedAreas() As Boolean
            For Each area As MASVisualOwnershipArea In ExpectedAreas()
                If Not Contains(area) Then Return False
            Next
            Return True
        End Function

        Friend Shared Function ExpectedAreas() As MASVisualOwnershipArea()
            Return New MASVisualOwnershipArea() {
                MASVisualOwnershipArea.Surface,
                MASVisualOwnershipArea.Shadow,
                MASVisualOwnershipArea.Effects,
                MASVisualOwnershipArea.Interaction,
                MASVisualOwnershipArea.ComponentChrome,
                MASVisualOwnershipArea.VisualPrimitives,
                MASVisualOwnershipArea.SharedTokens,
                MASVisualOwnershipArea.ThemeBoundary
            }
        End Function

        Friend Shared Function ExpectedAreaCount() As Integer
            Return ExpectedAreas().Length
        End Function

        Private Shared Function Normalize(value As String, fallback As String) As String
            Dim result As String = If(value, String.Empty).Trim()
            If result.Length = 0 Then Return fallback
            Return result
        End Function
    End Class

End Namespace
