Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports Nexamas.UI.Diagnostics

Namespace Nexamas.UI.Quality

    ''' <summary>
    ''' Commercial-readiness proof that runtime catch-site diagnostics are not limited to
    ''' synthetic record formatting. The gate exercises the real MASExceptionSilencer boundary
    ''' helpers used by render, input, and lifecycle catch sites and proves that each path reaches
    ''' the retained runtime-fault channel with the expected severity/category classification.
    ''' </summary>
    ''' <remarks>
    ''' The whole-repository source-contract gate in Run-NexamasUITestSuite.ps1 guards the static
    ''' catch-site classification policy. This runtime gate proves the live channel semantics for
    ''' the three catch-site families that were previously represented only by synthetic records.
    ''' </remarks>
    Friend NotInheritable Class MASRuntimeFaultCatchSiteClassificationGate

        Private Const RenderProbeContext As String = "MASRuntimeFaultCatchSiteClassificationGate.RenderProbe"
        Private Const InputProbeContext As String = "MASRuntimeFaultCatchSiteClassificationGate.InputProbe"
        Private Const LifecycleProbeContext As String = "MASRuntimeFaultCatchSiteClassificationGate.LifecycleProbe"

        Private Sub New()
        End Sub

        Friend Shared Function Passes() As Boolean
            Return EvaluateFindings().Count = 0
        End Function

        Friend Shared Function EvaluateFindings() As IReadOnlyList(Of MASCommercialReadinessFinding)
            Dim findings As New List(Of MASCommercialReadinessFinding)()

            ValidateRealBoundaryProbes(findings)
            ValidateStrictModeAgainstRealBoundaryHelpers(findings)

            Return findings
        End Function

        Private Shared Sub ValidateRealBoundaryProbes(findings As List(Of MASCommercialReadinessFinding))
            Dim previousThrowOnAny As Boolean = MASExceptionSilencer.ThrowOnSwallowedException
            Dim previousThrowOnLifecycle As Boolean = MASExceptionSilencer.ThrowOnLifecycleBreakingException
            Dim previousTraceRepeated As Boolean = MASExceptionSilencer.TraceRepeatedBoundaryExceptions

            Try
                Using scope As New MASRuntimeFaultStrictModeScope(False, False, False)
                    MASExceptionSilencer.SwallowRenderFallback(
                        New InvalidOperationException("Real render fallback catch-site probe."),
                        RenderProbeContext)

                    MASExceptionSilencer.SwallowInputBoundary(
                        New ArgumentException("Real input boundary catch-site probe."),
                        InputProbeContext)

                    MASExceptionSilencer.SwallowLifecycleBreaking(
                        New ApplicationException("Real lifecycle-breaking catch-site probe."),
                        LifecycleProbeContext)
                End Using
            Catch ex As Exception
                MASExceptionSilencer.ConfigureStrictness(previousThrowOnAny, previousThrowOnLifecycle, previousTraceRepeated)
                findings.Add(New MASCommercialReadinessFinding("runtime-faults", "CatchSiteRuntimeProbe", MASCommercialReadinessFindingSeverity.Error, "Real catch-site runtime probes threw unexpectedly: " & ex.GetType().FullName))
                Return
            End Try

            Dim records As IReadOnlyList(Of MASRuntimeFaultRecord) = MASRuntimeFaultChannel.GetRecentFaultsSnapshot()
            AssertPublished(records, RenderProbeContext, MASExceptionSeverity.Recoverable, MASExceptionHandlingCategory.RenderFallback, findings)
            AssertPublished(records, InputProbeContext, MASExceptionSeverity.BoundaryFailure, MASExceptionHandlingCategory.InputBoundary, findings)
            AssertPublished(records, LifecycleProbeContext, MASExceptionSeverity.CriticalStateTransition, MASExceptionHandlingCategory.LifecycleBreaking, findings)

            If MASExceptionSilencer.ThrowOnSwallowedException <> previousThrowOnAny OrElse
               MASExceptionSilencer.ThrowOnLifecycleBreakingException <> previousThrowOnLifecycle OrElse
               MASExceptionSilencer.TraceRepeatedBoundaryExceptions <> previousTraceRepeated Then

                MASExceptionSilencer.ConfigureStrictness(previousThrowOnAny, previousThrowOnLifecycle, previousTraceRepeated)
                findings.Add(New MASCommercialReadinessFinding("runtime-faults", "CatchSiteStrictnessRestore", MASCommercialReadinessFindingSeverity.Error, "Real catch-site runtime probes leaked strictness switches."))
            End If
        End Sub

        Private Shared Sub ValidateStrictModeAgainstRealBoundaryHelpers(findings As List(Of MASCommercialReadinessFinding))
            Dim renderStrictModeThrew As Boolean = False
            Dim lifecycleStrictModeThrew As Boolean = False

            Try
                Using scope As New MASRuntimeFaultStrictModeScope(True, False, True)
                    Try
                        MASExceptionSilencer.SwallowRenderFallback(
                            New InvalidOperationException("Strict render catch-site probe."),
                            RenderProbeContext & ".Strict")
                    Catch ex As InvalidOperationException
                        renderStrictModeThrew = ex.InnerException IsNot Nothing AndAlso TypeOf ex.InnerException Is InvalidOperationException
                        If Not renderStrictModeThrew Then
                            findings.Add(New MASCommercialReadinessFinding("runtime-faults", "CatchSiteStrictRender", MASCommercialReadinessFindingSeverity.Error, "Render strict-mode catch-site probe threw without the expected wrapped InvalidOperationException."))
                        End If
                    End Try
                End Using
            Catch ex As Exception
                findings.Add(New MASCommercialReadinessFinding("runtime-faults", "CatchSiteStrictRender", MASCommercialReadinessFindingSeverity.Error, "Render strict-mode catch-site probe failed: " & ex.GetType().FullName))
            End Try

            Try
                Using scope As New MASRuntimeFaultStrictModeScope(False, True, False)
                    Try
                        MASExceptionSilencer.SwallowLifecycleBreaking(
                            New ApplicationException("Strict lifecycle catch-site probe."),
                            LifecycleProbeContext & ".Strict")
                    Catch ex As InvalidOperationException
                        lifecycleStrictModeThrew = ex.InnerException IsNot Nothing AndAlso TypeOf ex.InnerException Is ApplicationException
                        If Not lifecycleStrictModeThrew Then
                            findings.Add(New MASCommercialReadinessFinding("runtime-faults", "CatchSiteStrictLifecycle", MASCommercialReadinessFindingSeverity.Error, "Lifecycle strict-mode catch-site probe threw without the expected wrapped ApplicationException."))
                        End If
                    End Try
                End Using
            Catch ex As Exception
                findings.Add(New MASCommercialReadinessFinding("runtime-faults", "CatchSiteStrictLifecycle", MASCommercialReadinessFindingSeverity.Error, "Lifecycle strict-mode catch-site probe failed: " & ex.GetType().FullName))
            End Try

            If Not renderStrictModeThrew Then
                findings.Add(New MASCommercialReadinessFinding("runtime-faults", "CatchSiteStrictRender", MASCommercialReadinessFindingSeverity.Error, "Strict mode did not fail fast through the real render fallback helper."))
            End If

            If Not lifecycleStrictModeThrew Then
                findings.Add(New MASCommercialReadinessFinding("runtime-faults", "CatchSiteStrictLifecycle", MASCommercialReadinessFindingSeverity.Error, "Lifecycle-only strict mode did not fail fast through the real lifecycle helper."))
            End If
        End Sub

        Private Shared Sub AssertPublished(records As IReadOnlyList(Of MASRuntimeFaultRecord),
                                           context As String,
                                           expectedSeverity As MASExceptionSeverity,
                                           expectedCategory As MASExceptionHandlingCategory,
                                           findings As List(Of MASCommercialReadinessFinding))
            If records Is Nothing Then
                findings.Add(New MASCommercialReadinessFinding("runtime-faults", "CatchSiteRuntimeChannel", MASCommercialReadinessFindingSeverity.Error, "Runtime fault channel returned Nothing while validating catch-site classification."))
                Return
            End If

            For index As Integer = records.Count - 1 To 0 Step -1
                Dim record As MASRuntimeFaultRecord = records(index)
                If record Is Nothing Then Continue For
                If Not String.Equals(record.Context, context, StringComparison.Ordinal) Then Continue For

                If record.Severity <> expectedSeverity OrElse record.Category <> expectedCategory Then
                    findings.Add(New MASCommercialReadinessFinding("runtime-faults", "CatchSiteRuntimeClassification", MASCommercialReadinessFindingSeverity.Error, "Catch-site runtime probe " & context & " reached the channel with " & record.Severity.ToString() & "/" & record.Category.ToString() & " instead of " & expectedSeverity.ToString() & "/" & expectedCategory.ToString() & "."))
                End If

                If String.IsNullOrWhiteSpace(record.ExceptionTypeName) OrElse String.IsNullOrWhiteSpace(record.Message) Then
                    findings.Add(New MASCommercialReadinessFinding("runtime-faults", "CatchSiteRuntimeSummary", MASCommercialReadinessFindingSeverity.Error, "Catch-site runtime probe " & context & " reached the channel without exception summary data."))
                End If

                Return
            Next

            findings.Add(New MASCommercialReadinessFinding("runtime-faults", "CatchSiteRuntimeVisibility", MASCommercialReadinessFindingSeverity.Error, "Catch-site runtime probe " & context & " did not reach the retained runtime fault channel."))
        End Sub

    End Class

End Namespace
