Option Strict On
Option Explicit On

Imports System.Collections.Generic
Imports System.Linq

Namespace Nexamas.UI.Virtualization

    ''' <summary>
    ''' Gate that protects Phase 3 from starting while the virtualization foundation is disconnected from existing item surfaces.
    ''' It does not activate virtualization inside those controls; it verifies that every current candidate is cataloged, type-linked,
    ''' and keeps Scroll/Layout/Selection ownership outside the virtualization engine.
    ''' </summary>
    Friend NotInheritable Class MASVirtualizationIntegrationGate

        Friend Const EmptyCatalogCode As String = "MASVirtualizationIntegration.EmptyCatalog"
        Friend Const DuplicateConsumerCode As String = "MASVirtualizationIntegration.DuplicateConsumer"
        Friend Const MissingRequiredConsumerCode As String = "MASVirtualizationIntegration.MissingRequiredConsumer"
        Friend Const InvalidBindingCode As String = "MASVirtualizationIntegration.InvalidBinding"
        Friend Const OwnershipLeakCode As String = "MASVirtualizationIntegration.OwnershipLeak"
        Friend Const InvalidExtentStrategyCode As String = "MASVirtualizationIntegration.InvalidExtentStrategy"
        Friend Const MissingAutoInvalidationCode As String = "MASVirtualizationIntegration.MissingAutoInvalidation"
        Friend Const InvalidComposedConsumerCode As String = "MASVirtualizationIntegration.InvalidComposedConsumer"

        Private Shared ReadOnly RequiredConsumerIds As IReadOnlyList(Of String) =
            New String() {
                "MASListBox",
                "MASListView",
                "MASDataGrid",
                "MASTreeView",
                "MASTileBox",
                "MASDropDownListFloatContent",
                "MASFileExplorerView"
            }

        Private Sub New()
        End Sub

        Friend Shared Function EvaluateCurrentConsumers() As MASVirtualizationIntegrationReport
            Return Evaluate(MASVirtualizationConsumerCatalog.GetCurrentConsumers())
        End Function

        Friend Shared Function Evaluate(bindings As IEnumerable(Of MASVirtualizationConsumerBinding)) As MASVirtualizationIntegrationReport
            Dim safeBindings = If(bindings, Enumerable.Empty(Of MASVirtualizationConsumerBinding)()).Where(Function(binding) binding IsNot Nothing).ToArray()
            Dim findings = New List(Of MASVirtualizationReadinessFinding)()

            If safeBindings.Length = 0 Then
                findings.Add(New MASVirtualizationReadinessFinding(EmptyCatalogCode, "Current virtualization consumer catalog must not be empty.", MASVirtualizationFindingSeverity.Error))
                Return New MASVirtualizationIntegrationReport(safeBindings, findings)
            End If

            Dim ids = New HashSet(Of String)(StringComparer.Ordinal)
            For Each binding In safeBindings
                If Not binding.IsStructurallyValid Then
                    findings.Add(New MASVirtualizationReadinessFinding(InvalidBindingCode, "Virtualization consumer binding is missing identity, type, or ownership facts.", MASVirtualizationFindingSeverity.Error))
                End If

                If binding.ConsumerType IsNot Nothing AndAlso Not binding.ConsumerType.IsClass Then
                    findings.Add(New MASVirtualizationReadinessFinding(InvalidBindingCode, "Virtualization consumer binding must reference a class type: " & binding.Id, MASVirtualizationFindingSeverity.Error))
                End If

                If Not binding.ScrollRemainsConsumerOwned OrElse Not binding.LayoutRemainsConsumerOwned OrElse Not binding.SelectionRemainsConsumerOwned Then
                    findings.Add(New MASVirtualizationReadinessFinding(OwnershipLeakCode, "Virtualization consumer binding leaks Scroll, Layout, or Selection ownership into the virtualization engine: " & binding.Id, MASVirtualizationFindingSeverity.Error))
                End If

                If Not binding.RequiresAutoInvalidationCoordinator OrElse Not binding.RequiresConsumerBoundaryAudit Then
                    findings.Add(New MASVirtualizationReadinessFinding(MissingAutoInvalidationCode, "Virtualization consumer binding must require auto invalidation and boundary audit metadata: " & binding.Id, MASVirtualizationFindingSeverity.Error))
                End If

                If Not System.Enum.IsDefined(GetType(MASVirtualizationConsumerKind), binding.Kind) OrElse
                   Not System.Enum.IsDefined(GetType(MASVirtualizationIntegrationStage), binding.Stage) OrElse
                   Not System.Enum.IsDefined(GetType(MASVirtualizationAxis), binding.RecommendedAxis) Then
                    findings.Add(New MASVirtualizationReadinessFinding(InvalidBindingCode, "Virtualization consumer binding contains an undefined kind, stage, or axis value: " & binding.Id, MASVirtualizationFindingSeverity.Error))
                End If

                If Not System.Enum.IsDefined(GetType(MASVirtualizationExtentStrategy), binding.ExtentStrategy) Then
                    findings.Add(New MASVirtualizationReadinessFinding(InvalidExtentStrategyCode, "Virtualization consumer binding contains an undefined extent strategy value: " & binding.Id, MASVirtualizationFindingSeverity.Error))
                End If

                If Not ids.Add(binding.Id) Then
                    findings.Add(New MASVirtualizationReadinessFinding(DuplicateConsumerCode, "Duplicate virtualization consumer id: " & binding.Id, MASVirtualizationFindingSeverity.Error))
                End If
            Next


            For Each binding In safeBindings
                If binding.Stage = MASVirtualizationIntegrationStage.ComposedSharedControllerConsumer Then
                    If Not binding.IsComposedSharedControllerConsumer Then
                        findings.Add(New MASVirtualizationReadinessFinding(InvalidComposedConsumerCode, "Composed virtualization consumer must consume through official child consumers: " & binding.Id, MASVirtualizationFindingSeverity.Error))
                    End If

                    For Each dependencyId As String In binding.ComposedThroughConsumerIds
                        If Not ids.Contains(dependencyId) Then
                            findings.Add(New MASVirtualizationReadinessFinding(InvalidComposedConsumerCode, "Composed virtualization consumer depends on an uncataloged child consumer: " & binding.Id & " -> " & dependencyId, MASVirtualizationFindingSeverity.Error))
                        End If
                    Next
                End If
            Next

            For Each requiredId In RequiredConsumerIds
                If Not ids.Contains(requiredId) Then
                    findings.Add(New MASVirtualizationReadinessFinding(MissingRequiredConsumerCode, "Missing virtualization consumer binding for current item surface: " & requiredId, MASVirtualizationFindingSeverity.Error))
                End If
            Next

            Return New MASVirtualizationIntegrationReport(safeBindings, findings)
        End Function

    End Class

End Namespace
