Option Strict On
Option Explicit On

Imports System

Namespace Nexamas.UI.Rendering

    ''' <summary>
    ''' Builds the surface-only scope boundary evidence.
    ''' This audit does not draw, create controls, run capture scenes, resolve layout, or expose public API.
    ''' </summary>
    Friend NotInheritable Class MASSurfaceTreatmentScopeBoundaryAudit

        Private Sub New()
        End Sub

        Friend Shared Function BuildSurfaceOnlyScopeBoundary() As MASSurfaceTreatmentScopeBoundaryReport
            Dim inventory As MASSurfaceTreatmentOwnershipReport = MASSurfaceTreatmentOwnershipInventoryBuilder.BuildCurrentSurfaceTreatmentInventory()
            Dim capture As MASSurfaceTreatmentCurrentVisualCaptureReport = MASSurfaceTreatmentCurrentVisualCaptureBuilder.BuildLowRiskCurrentVisualCapture()
            Dim runtime As MASSurfaceTreatmentRuntimeAlignmentReport = MASSurfaceTreatmentRuntimeAlignmentBuilder.BuildLowRiskRuntimeAlignment()
            Dim frameProof As MASSurfaceTreatmentFrameRuntimeProofPlanningReport = MASSurfaceTreatmentFrameRuntimeProofPlanningBuilder.BuildFrameRuntimeProofPlanning()
            Dim runtimeApplication As MASSurfaceTreatmentRuntimeSurfaceVisualApplicationReport = MASSurfaceTreatmentRuntimeSurfaceVisualApplicationBuilder.BuildRuntimeSurfaceVisualApplicationReadiness()
            Dim profiles As MASSurfaceTreatmentMaterialProfile() = MASSurfaceTreatmentMaterialProfileCatalog.RegisteredProfiles()

            Dim keepsGenericNames As Boolean = HasGenericMaterialNames(profiles)
            Dim excludesControls As Boolean = inventory.ExcludesInteractiveControlConsumers AndAlso
                                              capture.ExcludesInteractiveControls AndAlso
                                              runtime.ExcludesInteractiveControls AndAlso
                                              frameProof.ExcludesInteractiveControls AndAlso
                                              runtimeApplication.ExcludesInteractiveControls AndAlso
                                              MASSurfaceTreatmentConsumerCatalog.InteractiveControlsAreOutOfScope
            Dim noInteractiveControlPath As Boolean = excludesControls AndAlso
                                                 runtime.HighRiskBlockedCount = 0 AndAlso
                                                 frameProof.InteractiveControlBlockedCount = 0 AndAlso
                                                 runtimeApplication.ReadyForSurfaceVisualMaterialSelection
            Dim noParallelPath As Boolean = inventory.HasParallelSurfaceTreatmentSystemBlocker = False AndAlso
                                            inventory.ExistingMaterialRegistryName = NameOf(MASSurfaceMaterialRegistry) AndAlso
                                            inventory.OfficialFrameOwnerName = "VisualSurfaceFrame"

            Dim status As MASSurfaceTreatmentScopeBoundaryStatus = MASSurfaceTreatmentScopeBoundaryStatus.SurfaceOnlyScopeLocked
            If Not excludesControls Then status = MASSurfaceTreatmentScopeBoundaryStatus.BlockedByInteractiveControlConsumer
            If Not noInteractiveControlPath Then status = MASSurfaceTreatmentScopeBoundaryStatus.BlockedByInteractiveControlSurfaceTreatmentPath
            If Not noParallelPath Then status = MASSurfaceTreatmentScopeBoundaryStatus.BlockedByParallelMaterialOrFramePath

            Return New MASSurfaceTreatmentScopeBoundaryReport(
                name:="Surface Treatment Surface-Only Scope Boundary",
                status:=status,
                inventoryEntryCount:=If(inventory Is Nothing, 0, inventory.EntryCount),
                capturedLowRiskSurfaceCount:=If(capture Is Nothing, 0, capture.LowRiskCapturedCount),
                runtimeAlignedSurfaceCount:=If(runtime Is Nothing, 0, runtime.LowRiskAlignedCount),
                frameRuntimeProofPlanCount:=If(frameProof Is Nothing, 0, frameProof.LowRiskFrameRuntimeProofPlanCount),
                materialProfileCount:=If(profiles Is Nothing, 0, profiles.Length),
                keepsMaterialNamesGeneric:=keepsGenericNames,
                keepsInteractiveControlsOutOfSurfaceTreatment:=excludesControls,
                hasNoInteractiveControlSurfaceTreatmentPath:=noInteractiveControlPath,
                hasNoParallelMaterialOrFramePath:=noParallelPath)
        End Function

        Private Shared Function HasGenericMaterialNames(profiles As MASSurfaceTreatmentMaterialProfile()) As Boolean
            If profiles Is Nothing OrElse profiles.Length = 0 Then Return False

            Dim hasCrystal As Boolean = False
            Dim hasGlass As Boolean = False
            Dim hasWarmPaper As Boolean = False
            Dim hasGraphite As Boolean = False

            For Each profile As MASSurfaceTreatmentMaterialProfile In profiles
                If profile Is Nothing Then Continue For

                Dim key As String = If(profile.MaterialKey, String.Empty).Trim()
                If key.Length = 0 Then Return False
                If Not key.StartsWith("surface.material.", StringComparison.OrdinalIgnoreCase) Then Return False
                If ContainsElementSpecificMaterialName(key) Then Return False

                If String.Equals(key, MASSurfaceMaterialIds.CrystalIce, StringComparison.OrdinalIgnoreCase) Then hasCrystal = True
                If String.Equals(key, MASSurfaceMaterialIds.FrostedGlass, StringComparison.OrdinalIgnoreCase) Then hasGlass = True
                If String.Equals(key, MASSurfaceMaterialIds.WarmPaper, StringComparison.OrdinalIgnoreCase) Then hasWarmPaper = True
                If String.Equals(key, MASSurfaceMaterialIds.GraphiteMetal, StringComparison.OrdinalIgnoreCase) Then hasGraphite = True
            Next

            Return hasCrystal AndAlso hasGlass AndAlso hasWarmPaper AndAlso hasGraphite
        End Function

        Private Shared Function ContainsElementSpecificMaterialName(materialKey As String) As Boolean
            Dim key As String = If(materialKey, String.Empty).Trim().ToLowerInvariant()
            If key.Length = 0 Then Return True

            Dim blockedTerms As String() = New String() {"button", "grid", "avatar", "preview", "toolbar", "date", "time", "menu", "toast", "tooltip", "progressbar", "imageviewer"}
            For Each term As String In blockedTerms
                If key.IndexOf(term, StringComparison.Ordinal) >= 0 Then Return True
            Next

            Return False
        End Function

    End Class

End Namespace
