Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic

Namespace Nexamas.UI.Rendering

    ''' <summary>
    ''' Report proving that the material/frame pairing plan can be used for later runtime proof
    ''' by already captured low-risk consumers for already captured low-risk surface consumers.
    ''' </summary>
    Friend NotInheritable Class MASSurfaceTreatmentFrameRuntimeProofPlanningReport

        Private ReadOnly _entries As MASSurfaceTreatmentFrameRuntimeProofPlanningEntry()

        Friend ReadOnly Property Name As String
        Friend ReadOnly Property FramePairingReady As Boolean
        Friend ReadOnly Property RuntimeAlignmentReady As Boolean

        Friend Sub New(name As String,
                       entries As MASSurfaceTreatmentFrameRuntimeProofPlanningEntry(),
                       framePairingReady As Boolean,
                       runtimeAlignmentReady As Boolean)
            Me.Name = Normalize(name, "Surface Treatment Frame Pairing Runtime Proof Planning")
            Me._entries = If(entries, New MASSurfaceTreatmentFrameRuntimeProofPlanningEntry() {})
            Me.FramePairingReady = framePairingReady
            Me.RuntimeAlignmentReady = runtimeAlignmentReady
        End Sub

        Friend ReadOnly Property Entries As MASSurfaceTreatmentFrameRuntimeProofPlanningEntry()
            Get
                Return CType(_entries.Clone(), MASSurfaceTreatmentFrameRuntimeProofPlanningEntry())
            End Get
        End Property

        Friend ReadOnly Property EntryCount As Integer
            Get
                Return _entries.Length
            End Get
        End Property

        Friend ReadOnly Property LowRiskFrameRuntimeProofPlanCount As Integer
            Get
                Dim count As Integer = 0
                For Each entry As MASSurfaceTreatmentFrameRuntimeProofPlanningEntry In _entries
                    If entry IsNot Nothing AndAlso entry.IsLowRiskProofPlanned Then count += 1
                Next
                Return count
            End Get
        End Property

        Friend ReadOnly Property InteractiveControlBlockedCount As Integer
            Get
                Dim count As Integer = 0
                For Each entry As MASSurfaceTreatmentFrameRuntimeProofPlanningEntry In _entries
                    If entry IsNot Nothing AndAlso entry.IsInteractiveControlBlocked Then count += 1
                Next
                Return count
            End Get
        End Property

        Friend ReadOnly Property MaterialProfileCoverageCount As Integer
            Get
                Dim materials As New Dictionary(Of String, Boolean)(StringComparer.OrdinalIgnoreCase)
                For Each entry As MASSurfaceTreatmentFrameRuntimeProofPlanningEntry In _entries
                    If entry IsNot Nothing AndAlso entry.IsLowRiskProofPlanned Then materials(entry.MaterialKey) = True
                Next
                Return materials.Count
            End Get
        End Property

        Friend ReadOnly Property MaterialSpecificFrameRuntimeProofPlanCount As Integer
            Get
                Dim count As Integer = 0
                For Each entry As MASSurfaceTreatmentFrameRuntimeProofPlanningEntry In _entries
                    If entry IsNot Nothing AndAlso entry.UsesMaterialSpecificFrame Then count += 1
                Next
                Return count
            End Get
        End Property

        Friend ReadOnly Property CompatibilityAliasProofPlanCount As Integer
            Get
                Dim count As Integer = 0
                For Each entry As MASSurfaceTreatmentFrameRuntimeProofPlanningEntry In _entries
                    If entry IsNot Nothing AndAlso entry.IsLowRiskProofPlanned AndAlso entry.IsCompatibilityAlias Then count += 1
                Next
                Return count
            End Get
        End Property

        Friend ReadOnly Property IdentityPreservingProofPlanCount As Integer
            Get
                Dim count As Integer = 0
                For Each entry As MASSurfaceTreatmentFrameRuntimeProofPlanningEntry In _entries
                    If entry IsNot Nothing AndAlso entry.IsLowRiskProofPlanned AndAlso entry.PreservesMaterialIdentity Then count += 1
                Next
                Return count
            End Get
        End Property

        Friend ReadOnly Property HasLowRiskConsumerCoverage As Boolean
            Get
                For Each consumerKind As MASSurfaceTreatmentConsumerKind In MASSurfaceTreatmentConsumerCatalog.FrameRuntimeProofConsumers()
                    If Not ContainsLowRiskPlanFor(consumerKind) Then Return False
                Next
                Return MASSurfaceTreatmentConsumerCatalog.FrameRuntimeProofConsumerCount > 0
            End Get
        End Property

        Friend ReadOnly Property ExcludesInteractiveControls As Boolean
            Get
                Return InteractiveControlBlockedCount = 0
            End Get
        End Property

        Friend ReadOnly Property UsesOfficialSurfaceFrameOnly As Boolean
            Get
                For Each entry As MASSurfaceTreatmentFrameRuntimeProofPlanningEntry In _entries
                    If entry IsNot Nothing AndAlso Not entry.UsesOfficialSurfaceFrame Then Return False
                Next
                Return EntryCount > 0
            End Get
        End Property

        Friend ReadOnly Property KeepsSingleFrameStrengthModel As Boolean
            Get
                For Each entry As MASSurfaceTreatmentFrameRuntimeProofPlanningEntry In _entries
                    If entry IsNot Nothing AndAlso Not entry.KeepsSingleFrameStrengthModel Then Return False
                Next
                Return EntryCount > 0 AndAlso HasLevel1ThroughLevel6Evidence()
            End Get
        End Property

        Friend ReadOnly Property DefersRuntimeFrameRepaintForAllPlans As Boolean
            Get
                For Each entry As MASSurfaceTreatmentFrameRuntimeProofPlanningEntry In _entries
                    If entry IsNot Nothing AndAlso Not entry.DefersRuntimeFrameRepaint Then Return False
                Next
                Return EntryCount > 0
            End Get
        End Property
        Friend ReadOnly Property ReadyForFutureFrameRuntimeProofPlanning As Boolean
            Get
                Return FramePairingReady AndAlso
                       RuntimeAlignmentReady AndAlso
                       EntryCount = MASSurfaceTreatmentConsumerCatalog.ExpectedFrameRuntimeProofPlanCount(MASSurfaceTreatmentMaterialProfileCatalog.RegisteredProfiles().Length) AndAlso
                       LowRiskFrameRuntimeProofPlanCount = MASSurfaceTreatmentConsumerCatalog.ExpectedFrameRuntimeProofPlanCount(MASSurfaceTreatmentMaterialProfileCatalog.RegisteredProfiles().Length) AndAlso
                       InteractiveControlBlockedCount = 0 AndAlso
                       MaterialProfileCoverageCount = 8 AndAlso
                       MaterialSpecificFrameRuntimeProofPlanCount >= 15 AndAlso
                       CompatibilityAliasProofPlanCount = 0 AndAlso
                       HasLowRiskConsumerCoverage AndAlso
                       ExcludesInteractiveControls AndAlso
                       UsesOfficialSurfaceFrameOnly AndAlso
                       KeepsSingleFrameStrengthModel AndAlso
                       DefersRuntimeFrameRepaintForAllPlans AndAlso
                       Not ContainsStatus(MASSurfaceTreatmentFrameRuntimeProofPlanningStatus.BlockedByFramePairingEvidence) AndAlso
                       Not ContainsStatus(MASSurfaceTreatmentFrameRuntimeProofPlanningStatus.BlockedByRuntimeAlignmentEvidence) AndAlso
                       Not ContainsStatus(MASSurfaceTreatmentFrameRuntimeProofPlanningStatus.BlockedByFrameOverrideMismatch)
            End Get
        End Property

        Friend Function ContainsStatus(status As MASSurfaceTreatmentFrameRuntimeProofPlanningStatus) As Boolean
            For Each entry As MASSurfaceTreatmentFrameRuntimeProofPlanningEntry In _entries
                If entry IsNot Nothing AndAlso entry.Status = status Then Return True
            Next
            Return False
        End Function

        Friend Function ContainsPlan(consumerKind As MASSurfaceTreatmentConsumerKind,
                                     materialKey As String,
                                     frameKey As String) As Boolean
            For Each entry As MASSurfaceTreatmentFrameRuntimeProofPlanningEntry In _entries
                If entry IsNot Nothing AndAlso
                   entry.IsLowRiskProofPlanned AndAlso
                   entry.ConsumerKind = consumerKind AndAlso
                   String.Equals(entry.MaterialKey, materialKey, StringComparison.OrdinalIgnoreCase) AndAlso
                   String.Equals(entry.PlannedFrameKey, frameKey, StringComparison.OrdinalIgnoreCase) Then
                    Return True
                End If
            Next
            Return False
        End Function

        Friend Function ContainsLowRiskPlanFor(consumerKind As MASSurfaceTreatmentConsumerKind) As Boolean
            For Each entry As MASSurfaceTreatmentFrameRuntimeProofPlanningEntry In _entries
                If entry IsNot Nothing AndAlso entry.ConsumerKind = consumerKind AndAlso entry.IsLowRiskProofPlanned Then Return True
            Next
            Return False
        End Function
        Private Function HasLevel1ThroughLevel6Evidence() As Boolean
            Dim strengths As MASSurfaceFrameStrength() = New MASSurfaceFrameStrength() {
                MASSurfaceFrameStrength.Level1,
                MASSurfaceFrameStrength.Level2,
                MASSurfaceFrameStrength.Level3,
                MASSurfaceFrameStrength.Level4,
                MASSurfaceFrameStrength.Level5,
                MASSurfaceFrameStrength.Level6
            }

            For Each strength As MASSurfaceFrameStrength In strengths
                If Not [Enum].IsDefined(GetType(MASSurfaceFrameStrength), strength) Then Return False
            Next

            Return strengths.Length = 6
        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
