Option Strict On
Option Explicit On

Imports System

Namespace Nexamas.UI.Rendering

    ''' <summary>
    ''' Report describing planned material-specific frame pairings.
    ''' It verifies that frame ids live in VisualSurfaceFrame and that Level1-Level6 remains the only strength model.
    ''' </summary>
    Friend NotInheritable Class MASSurfaceTreatmentFramePairingReport

        Private ReadOnly _entries As MASSurfaceTreatmentFramePairingEntry()

        Friend ReadOnly Property Name As String

        Friend Sub New(name As String,
                       entries As MASSurfaceTreatmentFramePairingEntry())
            Me.Name = Normalize(name, "Surface Treatment Low-Risk Material/Frame Pairing Plan")
            Me._entries = If(entries, New MASSurfaceTreatmentFramePairingEntry() {})
        End Sub

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

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

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

        Friend ReadOnly Property MaterialSpecificFramePairingCount As Integer
            Get
                Dim count As Integer = 0
                For Each entry As MASSurfaceTreatmentFramePairingEntry In _entries
                    If entry IsNot Nothing AndAlso
                       entry.IsPlannedPairing AndAlso
                       Not String.Equals(entry.RecommendedFrameKey, MASSurfaceFrameIds.PlatformDefault, StringComparison.OrdinalIgnoreCase) AndAlso
                       Not entry.IsCompatibilityAlias Then
                        count += 1
                    End If
                Next
                Return count
            End Get
        End Property

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

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

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

        Friend ReadOnly Property HasSingleFrameStrengthModel As Boolean
            Get
                For Each entry As MASSurfaceTreatmentFramePairingEntry 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 DefersRuntimeFrameRepaintForAllPairings As Boolean
            Get
                For Each entry As MASSurfaceTreatmentFramePairingEntry In _entries
                    If entry IsNot Nothing AndAlso Not entry.DefersRuntimeFrameRepaint Then Return False
                Next
                Return EntryCount > 0
            End Get
        End Property

        Friend ReadOnly Property HasNoParallelFrameSystemBlocker As Boolean
            Get
                Return Not ContainsStatus(MASSurfaceTreatmentFramePairingStatus.BlockedByParallelFrameSystem)
            End Get
        End Property

        Friend ReadOnly Property ReadyForLowRiskFramePairingProof As Boolean
            Get
                Return EntryCount >= 8 AndAlso
                       PlannedPairingCount = EntryCount AndAlso
                       MaterialSpecificFramePairingCount >= 5 AndAlso
                       CompatibilityAliasCount = 0 AndAlso
                       IdentityPreservingPairingCount >= 5 AndAlso
                       HasOfficialSurfaceFrameOnly AndAlso
                       HasSingleFrameStrengthModel AndAlso
                       DefersRuntimeFrameRepaintForAllPairings AndAlso
                       HasNoParallelFrameSystemBlocker
            End Get
        End Property

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

        Friend Function ContainsPairing(materialKey As String,
                                        frameKey As String) As Boolean
            For Each entry As MASSurfaceTreatmentFramePairingEntry In _entries
                If entry IsNot Nothing AndAlso
                   String.Equals(entry.MaterialKey, materialKey, StringComparison.OrdinalIgnoreCase) AndAlso
                   String.Equals(entry.RecommendedFrameKey, frameKey, StringComparison.OrdinalIgnoreCase) Then
                    Return True
                End If
            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
