Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.FloatRuntime

    ''' <summary>
    ''' Immutable internal final-closure manifest for FloatRuntime commercial overlay governance.
    ''' </summary>
    ''' <remarks>
    ''' This contract does not open floats, create controls, route input, render, schedule transitions,
    ''' mutate host state, allocate bitmap resources, or expose a public telemetry API. It records only
    ''' registry, lifecycle-policy, presentation-profile, and ownership-boundary facts from an already
    ''' bootstrapped FloatRuntime registry.
    ''' </remarks>
    Friend NotInheritable Class MASFloatRuntimeGovernanceClosureManifest
        Private ReadOnly _registeredFloatKeys As IReadOnlyList(Of String)
        Private ReadOnly _requiredFloatKeys As IReadOnlyList(Of String)
        Private ReadOnly _requiredGateNames As IReadOnlyList(Of String)
        Private ReadOnly _evidenceReportNames As IReadOnlyList(Of String)
        Private ReadOnly _ownershipContracts As IReadOnlyList(Of String)
        Private ReadOnly _consumerFacadeContracts As IReadOnlyList(Of String)

        Friend Sub New(status As MASFloatRuntimeGovernanceClosureStatus,
                       closureName As String,
                       closureId As String,
                       registeredFloatKeys As IEnumerable(Of String),
                       requiredFloatKeys As IEnumerable(Of String),
                       requiredGateNames As IEnumerable(Of String),
                       evidenceReportNames As IEnumerable(Of String),
                       ownershipContracts As IEnumerable(Of String),
                       consumerFacadeContracts As IEnumerable(Of String),
                       hasDescriptorRegistry As Boolean,
                       hasLifecyclePolicyGovernance As Boolean,
                       hasPresentationProfileGovernance As Boolean,
                       hasInputFocusRoutingGovernance As Boolean,
                       hasPublicFacadeBoundary As Boolean,
                       summary As String)
            Me.Status = status
            Me.ClosureName = NormalizeText(closureName)
            Me.ClosureId = NormalizeText(closureId)
            _registeredFloatKeys = New ReadOnlyCollection(Of String)(NormalizeList(registeredFloatKeys))
            _requiredFloatKeys = New ReadOnlyCollection(Of String)(NormalizeList(requiredFloatKeys))
            _requiredGateNames = New ReadOnlyCollection(Of String)(NormalizeList(requiredGateNames))
            _evidenceReportNames = New ReadOnlyCollection(Of String)(NormalizeList(evidenceReportNames))
            _ownershipContracts = New ReadOnlyCollection(Of String)(NormalizeList(ownershipContracts))
            _consumerFacadeContracts = New ReadOnlyCollection(Of String)(NormalizeList(consumerFacadeContracts))
            Me.HasDescriptorRegistry = hasDescriptorRegistry
            Me.HasLifecyclePolicyGovernance = hasLifecyclePolicyGovernance
            Me.HasPresentationProfileGovernance = hasPresentationProfileGovernance
            Me.HasInputFocusRoutingGovernance = hasInputFocusRoutingGovernance
            Me.HasPublicFacadeBoundary = hasPublicFacadeBoundary
            Me.Summary = NormalizeText(summary)
        End Sub

        Friend ReadOnly Property Status As MASFloatRuntimeGovernanceClosureStatus
        Friend ReadOnly Property ClosureName As String
        Friend ReadOnly Property ClosureId As String
        Friend ReadOnly Property HasDescriptorRegistry As Boolean
        Friend ReadOnly Property HasLifecyclePolicyGovernance As Boolean
        Friend ReadOnly Property HasPresentationProfileGovernance As Boolean
        Friend ReadOnly Property HasInputFocusRoutingGovernance As Boolean
        Friend ReadOnly Property HasPublicFacadeBoundary As Boolean
        Friend ReadOnly Property Summary As String

        Friend ReadOnly Property RegisteredFloatKeys As IReadOnlyList(Of String)
            Get
                Return _registeredFloatKeys
            End Get
        End Property

        Friend ReadOnly Property RequiredFloatKeys As IReadOnlyList(Of String)
            Get
                Return _requiredFloatKeys
            End Get
        End Property

        Friend ReadOnly Property RequiredGateNames As IReadOnlyList(Of String)
            Get
                Return _requiredGateNames
            End Get
        End Property

        Friend ReadOnly Property EvidenceReportNames As IReadOnlyList(Of String)
            Get
                Return _evidenceReportNames
            End Get
        End Property

        Friend ReadOnly Property OwnershipContracts As IReadOnlyList(Of String)
            Get
                Return _ownershipContracts
            End Get
        End Property

        Friend ReadOnly Property ConsumerFacadeContracts As IReadOnlyList(Of String)
            Get
                Return _consumerFacadeContracts
            End Get
        End Property

        Friend ReadOnly Property HasCompleteFloatRuntimeGovernanceChain As Boolean
            Get
                Return Not String.IsNullOrWhiteSpace(ClosureName) AndAlso
                       Not String.IsNullOrWhiteSpace(ClosureId) AndAlso
                       RequiredFloatKeys.Count >= 12 AndAlso
                       RegisteredFloatKeys.Count >= RequiredFloatKeys.Count AndAlso
                       RequiredGateNames.Count >= 4 AndAlso
                       EvidenceReportNames.Count >= 8 AndAlso
                       OwnershipContracts.Count >= 15 AndAlso
                       ConsumerFacadeContracts.Count >= 7 AndAlso
                       HasDescriptorRegistry AndAlso
                       HasLifecyclePolicyGovernance AndAlso
                       HasPresentationProfileGovernance AndAlso
                       HasInputFocusRoutingGovernance AndAlso
                       HasPublicFacadeBoundary
            End Get
        End Property

        Friend ReadOnly Property IsClosed As Boolean
            Get
                Return Status = MASFloatRuntimeGovernanceClosureStatus.Closed AndAlso
                       HasCompleteFloatRuntimeGovernanceChain
            End Get
        End Property

        Friend ReadOnly Property HasClosureBlocker As Boolean
            Get
                Return Status <> MASFloatRuntimeGovernanceClosureStatus.Closed OrElse
                       Not HasCompleteFloatRuntimeGovernanceChain
            End Get
        End Property

        Friend Shared Function CreateFromRuntime(runtime As MASFloatRuntime,
                                                 closureName As String) As MASFloatRuntimeGovernanceClosureManifest
            If runtime Is Nothing Then
                Return CreateIncomplete(closureName)
            End If

            Return CreateFromRegistry(runtime.Registry, closureName)
        End Function

        Friend Shared Function CreateFromRegistry(registry As MASFloatRegistry,
                                                  closureName As String) As MASFloatRuntimeGovernanceClosureManifest
            If registry Is Nothing Then
                Return CreateIncomplete(closureName)
            End If

            Dim requiredKeys As IReadOnlyList(Of String) = CreateRequiredFloatKeys()
            Dim registeredKeys As IReadOnlyList(Of String) = registry.GetRegisteredKeys()
            Dim hasRegistry As Boolean = HasAllRequiredKeys(registeredKeys, requiredKeys)
            Dim hasLifecyclePolicy As Boolean = ResolveLifecyclePolicyGovernance(registry)
            Dim hasPresentationGovernance As Boolean = ResolvePresentationProfileGovernance(registry)
            Dim hasInputFocusGovernance As Boolean = hasLifecyclePolicy AndAlso hasRegistry
            Dim hasPublicBoundary As Boolean = hasRegistry
            Dim status As MASFloatRuntimeGovernanceClosureStatus = ResolveStatus(registry, hasRegistry, hasLifecyclePolicy, hasPresentationGovernance)
            Dim name As String = If(String.IsNullOrWhiteSpace(closureName),
                                    "FloatRuntime Overlay Governance Final Closure",
                                    closureName.Trim())
            Dim closureId As String = "MAS-FLOATRUNTIME-OVERLAY-GOVERNANCE-CLOSURE-2026-06-19"

            Return New MASFloatRuntimeGovernanceClosureManifest(
                status,
                name,
                closureId,
                registeredKeys,
                requiredKeys,
                CreateRequiredGateNames(),
                CreateEvidenceReportNames(),
                CreateOwnershipContracts(),
                CreateConsumerFacadeContracts(),
                hasRegistry,
                hasLifecyclePolicy,
                hasPresentationGovernance,
                hasInputFocusGovernance,
                hasPublicBoundary,
                ResolveSummary(status))
        End Function

        Private Shared Function CreateIncomplete(closureName As String) As MASFloatRuntimeGovernanceClosureManifest
            Dim name As String = If(String.IsNullOrWhiteSpace(closureName),
                                    "FloatRuntime Overlay Governance Final Closure",
                                    closureName.Trim())

            Return New MASFloatRuntimeGovernanceClosureManifest(
                MASFloatRuntimeGovernanceClosureStatus.IncompleteGovernance,
                name,
                "MAS-FLOATRUNTIME-OVERLAY-GOVERNANCE-CLOSURE-2026-06-19",
                New List(Of String)(),
                CreateRequiredFloatKeys(),
                CreateRequiredGateNames(),
                CreateEvidenceReportNames(),
                CreateOwnershipContracts(),
                CreateConsumerFacadeContracts(),
                hasDescriptorRegistry:=False,
                hasLifecyclePolicyGovernance:=False,
                hasPresentationProfileGovernance:=False,
                hasInputFocusRoutingGovernance:=False,
                hasPublicFacadeBoundary:=False,
                summary:=ResolveSummary(MASFloatRuntimeGovernanceClosureStatus.IncompleteGovernance))
        End Function

        Private Shared Function ResolveStatus(registry As MASFloatRegistry,
                                              hasRegistry As Boolean,
                                              hasLifecyclePolicy As Boolean,
                                              hasPresentationGovernance As Boolean) As MASFloatRuntimeGovernanceClosureStatus
            If registry Is Nothing Then
                Return MASFloatRuntimeGovernanceClosureStatus.IncompleteGovernance
            End If

            If Not hasRegistry Then
                Return MASFloatRuntimeGovernanceClosureStatus.BlockedByDescriptorRegistry
            End If

            If Not hasLifecyclePolicy Then
                Return MASFloatRuntimeGovernanceClosureStatus.BlockedByLifecyclePolicy
            End If

            If Not hasPresentationGovernance Then
                Return MASFloatRuntimeGovernanceClosureStatus.BlockedByPresentationGovernance
            End If

            Return MASFloatRuntimeGovernanceClosureStatus.Closed
        End Function

        Private Shared Function ResolveLifecyclePolicyGovernance(registry As MASFloatRegistry) As Boolean
            Dim messageDescriptor As MASFloatDescriptor = Nothing
            Dim panelDescriptor As MASFloatDescriptor = Nothing
            Dim dropDownDescriptor As MASFloatDescriptor = Nothing
            Dim menuBarDescriptor As MASFloatDescriptor = Nothing
            Dim contextDescriptor As MASFloatDescriptor = Nothing
            Dim tooltipDescriptor As MASFloatDescriptor = Nothing
            Dim toastDescriptor As MASFloatDescriptor = Nothing
            Dim drawerDescriptor As MASFloatDescriptor = Nothing

            Return registry.TryFind(MASFloatKeys.MessageBox, messageDescriptor) AndAlso
                   registry.TryFind(MASFloatKeys.Panel, panelDescriptor) AndAlso
                   registry.TryFind(MASFloatKeys.DropDownMenu, dropDownDescriptor) AndAlso
                   registry.TryFind(MASFloatKeys.MenuBarDropDownMenu, menuBarDescriptor) AndAlso
                   registry.TryFind(MASFloatKeys.ContextMenu, contextDescriptor) AndAlso
                   registry.TryFind(MASFloatKeys.Tooltip, tooltipDescriptor) AndAlso
                   registry.TryFind(MASFloatKeys.Toast, toastDescriptor) AndAlso
                   registry.TryFind(MASFloatKeys.Drawer, drawerDescriptor) AndAlso
                   messageDescriptor.DefaultLayer = MASFloatLayerLevel.Modal AndAlso
                   panelDescriptor.DefaultLayer = MASFloatLayerLevel.Modal AndAlso
                   dropDownDescriptor.DefaultSlot = MASFloatSlot.Popup AndAlso
                   menuBarDescriptor.DefaultSlot = MASFloatSlot.Popup AndAlso
                   contextDescriptor.DefaultSlot = MASFloatSlot.Popup AndAlso
                   tooltipDescriptor.DefaultSlot = MASFloatSlot.Tooltip AndAlso
                   toastDescriptor.DefaultSlot = MASFloatSlot.System AndAlso
                   drawerDescriptor.DefaultSlot = MASFloatSlot.MainModal AndAlso
                   drawerDescriptor.DefaultLayer = MASFloatLayerLevel.Modal AndAlso
                   HasCapability(messageDescriptor, MASFloatCapabilities.ModalBlocking) AndAlso
                   HasCapability(messageDescriptor, MASFloatCapabilities.OwnsFocus) AndAlso
                   HasCapability(panelDescriptor, MASFloatCapabilities.ModalBlocking) AndAlso
                   HasCapability(dropDownDescriptor, MASFloatCapabilities.OutsideDismiss) AndAlso
                   HasCapability(menuBarDescriptor, MASFloatCapabilities.OutsideDismiss) AndAlso
                   HasCapability(menuBarDescriptor, MASFloatCapabilities.EscapeDismiss) AndAlso
                   HasCapability(contextDescriptor, MASFloatCapabilities.EscapeDismiss) AndAlso
                   Not HasCapability(tooltipDescriptor, MASFloatCapabilities.ModalBlocking) AndAlso
                   Not HasCapability(toastDescriptor, MASFloatCapabilities.ModalBlocking) AndAlso
                   HasCapability(drawerDescriptor, MASFloatCapabilities.ModalBlocking) AndAlso
                   HasCapability(drawerDescriptor, MASFloatCapabilities.OutsideDismiss) AndAlso
                   HasCapability(drawerDescriptor, MASFloatCapabilities.OwnsFocus)
        End Function

        Private Shared Function ResolvePresentationProfileGovernance(registry As MASFloatRegistry) As Boolean
            Dim messageDescriptor As MASFloatDescriptor = Nothing
            Dim menuDescriptor As MASFloatDescriptor = Nothing
            Dim menuBarDescriptor As MASFloatDescriptor = Nothing
            Dim listDescriptor As MASFloatDescriptor = Nothing
            Dim contextDescriptor As MASFloatDescriptor = Nothing
            Dim tooltipDescriptor As MASFloatDescriptor = Nothing
            Dim toastDescriptor As MASFloatDescriptor = Nothing
            Dim progressDescriptor As MASFloatDescriptor = Nothing
            Dim drawerDescriptor As MASFloatDescriptor = Nothing

            If Not registry.TryFind(MASFloatKeys.MessageBox, messageDescriptor) Then Return False
            If Not registry.TryFind(MASFloatKeys.DropDownMenu, menuDescriptor) Then Return False
            If Not registry.TryFind(MASFloatKeys.MenuBarDropDownMenu, menuBarDescriptor) Then Return False
            If Not registry.TryFind(MASFloatKeys.DropDownList, listDescriptor) Then Return False
            If Not registry.TryFind(MASFloatKeys.ContextMenu, contextDescriptor) Then Return False
            If Not registry.TryFind(MASFloatKeys.Tooltip, tooltipDescriptor) Then Return False
            If Not registry.TryFind(MASFloatKeys.Toast, toastDescriptor) Then Return False
            If Not registry.TryFind(MASFloatKeys.Progress, progressDescriptor) Then Return False
            If Not registry.TryFind(MASFloatKeys.Drawer, drawerDescriptor) Then Return False

            Return HasPresentation(messageDescriptor, MASFloatPlacement.Center, MASFloatTransitionOriginKind.BoundsCenter, expectsDim:=True) AndAlso
                   HasPresentation(menuDescriptor, MASFloatPlacement.Fullscreen, MASFloatTransitionOriginKind.AnchorBottomLeft, expectsDim:=False) AndAlso
                   HasPresentation(menuBarDescriptor, MASFloatPlacement.Fullscreen, MASFloatTransitionOriginKind.AnchorBottomLeft, expectsDim:=False) AndAlso
                   HasPresentation(listDescriptor, MASFloatPlacement.ExplicitBounds, MASFloatTransitionOriginKind.BoundsTopCenter, expectsDim:=False) AndAlso
                   HasPresentation(contextDescriptor, MASFloatPlacement.Fullscreen, MASFloatTransitionOriginKind.AnchorTopLeft, expectsDim:=False) AndAlso
                   HasPresentation(tooltipDescriptor, MASFloatPlacement.Fullscreen, MASFloatTransitionOriginKind.AnchorTopCenter, expectsDim:=False) AndAlso
                   HasPresentation(toastDescriptor, MASFloatPlacement.Fullscreen, MASFloatTransitionOriginKind.BoundsBottomCenter, expectsDim:=False) AndAlso
                   HasPresentation(progressDescriptor, MASFloatPlacement.Center, MASFloatTransitionOriginKind.BoundsCenter, expectsDim:=False) AndAlso
                   HasPresentation(drawerDescriptor, MASFloatPlacement.DockRight, MASFloatTransitionOriginKind.BoundsTopCenter, expectsDim:=True)
        End Function

        Private Shared Function HasPresentation(descriptor As MASFloatDescriptor,
                                                placement As MASFloatPlacement,
                                                origin As MASFloatTransitionOriginKind,
                                                expectsDim As Boolean) As Boolean
            If descriptor Is Nothing OrElse descriptor.DefaultPresentation Is Nothing Then Return False

            Return descriptor.DefaultPresentation.Placement = placement AndAlso
                   descriptor.DefaultPresentation.TransitionOrigin = origin AndAlso
                   descriptor.DefaultPresentation.DimBackground = expectsDim AndAlso
                   descriptor.DefaultPresentation.DurationMs >= 0
        End Function

        Private Shared Function HasCapability(descriptor As MASFloatDescriptor,
                                              capability As MASFloatCapabilities) As Boolean
            If descriptor Is Nothing Then Return False
            Return (descriptor.Capabilities And capability) = capability
        End Function

        Private Shared Function HasAllRequiredKeys(registeredKeys As IReadOnlyList(Of String),
                                                   requiredKeys As IReadOnlyList(Of String)) As Boolean
            If registeredKeys Is Nothing OrElse requiredKeys Is Nothing Then Return False

            For Each requiredKey As String In requiredKeys
                Dim found As Boolean = False
                For Each registeredKey As String In registeredKeys
                    If String.Equals(registeredKey, requiredKey, StringComparison.Ordinal) Then
                        found = True
                        Exit For
                    End If
                Next

                If Not found Then Return False
            Next

            Return True
        End Function

        Private Shared Function ResolveSummary(status As MASFloatRuntimeGovernanceClosureStatus) As String
            Select Case status
                Case MASFloatRuntimeGovernanceClosureStatus.Closed
                    Return "FloatRuntime overlay governance is closed: descriptors, lifecycle policy, focus/input routing, presentation profiles, and public facade boundaries are governed."
                Case MASFloatRuntimeGovernanceClosureStatus.BlockedByDescriptorRegistry
                    Return "FloatRuntime closure is blocked because one or more built-in descriptor keys are not registered."
                Case MASFloatRuntimeGovernanceClosureStatus.BlockedByLifecyclePolicy
                    Return "FloatRuntime closure is blocked because modal, popup, passive, or system lifecycle policy facts are incomplete."
                Case MASFloatRuntimeGovernanceClosureStatus.BlockedByPresentationGovernance
                    Return "FloatRuntime closure is blocked because built-in presentation profiles are incomplete or not centrally governed."
                Case Else
                    Return "FloatRuntime closure is incomplete because the runtime or registry evidence is missing."
            End Select
        End Function

        Private Shared Function CreateRequiredFloatKeys() As IReadOnlyList(Of String)
            Return New ReadOnlyCollection(Of String)(New List(Of String) From {
                MASFloatKeys.MessageBox,
                MASFloatKeys.Panel,
                MASFloatKeys.FilePicker,
                MASFloatKeys.FileExplorer,
                MASFloatKeys.FileExplorerViewModeMenu,
                MASFloatKeys.DropDownMenu,
                MASFloatKeys.MenuBarDropDownMenu,
                MASFloatKeys.DropDownList,
                MASFloatKeys.ContextMenu,
                MASFloatKeys.Tooltip,
                MASFloatKeys.Toast,
                MASFloatKeys.Progress,
                MASFloatKeys.Drawer
            })
        End Function

        Private Shared Function CreateRequiredGateNames() As IReadOnlyList(Of String)
            Return New ReadOnlyCollection(Of String)(New List(Of String) From {
                "tools/quality/Run-NexamasUIQuality.ps1",
                "tools/quality/Run-NexamasUIQuality.ps1",
                "tools/quality/Run-NexamasUIQuality.ps1",
                "tools/quality/Run-NexamasUIQuality.ps1"
            })
        End Function

        Private Shared Function CreateEvidenceReportNames() As IReadOnlyList(Of String)
            Return New ReadOnlyCollection(Of String)(New List(Of String) From {
                "OverlayFloatGuide.md",
                "PanelShellFloatSurgicalAudit.md",
                "MAS_DIALOG_FLOAT_PROGRESS_ALIGNMENT_AUDIT.md",
                "MAS_EXISTING_DIALOG_CONSUMERS_ALIGNMENT.md",
                "TOAST_API_LOCKDOWN.md",
                "TOOLTIP_API_LOCKDOWN.md",
                "MENUS_API_LOCKDOWN.md",
                "MAS_PUBLIC_API_SURFACE_LOCKDOWN_PHASE17_FLOATRUNTIME_INTERNAL_MEMBER_TIGHTENING.md",
                "MAS_MOTION_AESTHETIC_RUNTIME_PASS_2026_06_18.md",
                "MAS_FLOATRUNTIME_OVERLAY_GOVERNANCE_FINAL_CLOSURE_2026_06_19.md"
            })
        End Function

        Private Shared Function CreateOwnershipContracts() As IReadOnlyList(Of String)
            Return New ReadOnlyCollection(Of String)(New List(Of String) From {
                "MASFloatRuntime",
                "MASFloatRegistry",
                "MASFloatBootstrap",
                "MASFloatDescriptor",
                "MASFloatRequest",
                "MASFloatOwnerToken",
                "MASFloatCoordinator",
                "MASFloatPolicyEngine",
                "MASFloatRuntimeState",
                "MASFloatSlotState",
                "MASFloatLifecycleRecord",
                "MASFloatHost",
                "MASFloatHostState",
                "MASFloatPresentationEngine",
                "MASFloatTransitionEngine",
                "MASFloatPresentationProfiles",
                "MASFloatInputRouter",
                "MASFloatFocusManager",
                "MASFloatHostPresenter"
            })
        End Function

        Private Shared Function CreateConsumerFacadeContracts() As IReadOnlyList(Of String)
            Return New ReadOnlyCollection(Of String)(New List(Of String) From {
                "MASApplicationWindowDialogs",
                "MASApplicationWindowToasts",
                "MASApplicationWindowTooltips",
                "MASApplicationWindowContextMenus",
                "MASApplicationWindowShell",
                "MASFilePickerService.FloatRequests",
                "MASSkiaHostFloatRuntimeCoordinator",
                "MASSkiaRootHost.FloatFacades",
                "MASApplicationWindowControls.CreateDrawer"
            })
        End Function

        Private Shared Function NormalizeText(value As String) As String
            Return If(value, String.Empty).Trim()
        End Function

        Private Shared Function NormalizeList(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 = NormalizeText(value)
                If normalized.Length > 0 AndAlso Not result.Contains(normalized) Then
                    result.Add(normalized)
                End If
            Next

            Return result
        End Function

    End Class

End Namespace
