Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Quality

    ''' <summary>
    ''' Friend-only governance gate for runtime fault developer visibility and strict mode.
    ''' </summary>
    ''' <remarks>
    ''' This gate does not require an empty runtime fault channel. Existing faults are valid
    ''' diagnostic evidence. The gate proves that faults can be summarized through the official
    ''' channel and that strict swallowed-exception mode can be enabled and restored safely.
    ''' </remarks>
    Friend NotInheritable Class MASRuntimeFaultStrictModeGate

        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)()

            ValidateDeveloperPanelSnapshot(findings)
            ValidateStrictModeScope(findings)

            Return findings
        End Function

        Private Shared Sub ValidateDeveloperPanelSnapshot(findings As List(Of MASCommercialReadinessFinding))
            Dim records As New List(Of MASRuntimeFaultRecord)()
            Dim nowUtc As DateTimeOffset = Nexamas.UI.Timing.MASTimeProvider.UtcNowOffset()

            records.Add(New MASRuntimeFaultRecord(
                nowUtc,
                MASExceptionSeverity.Recoverable,
                MASExceptionHandlingCategory.RenderFallback,
                "RuntimeFaultGate.RenderFallback",
                "MASRuntimeFaultStrictModeGate.vb",
                1,
                GetType(InvalidOperationException).FullName,
                "Synthetic render fallback probe.",
                1,
                True))

            records.Add(New MASRuntimeFaultRecord(
                nowUtc.AddMilliseconds(1),
                MASExceptionSeverity.BoundaryFailure,
                MASExceptionHandlingCategory.InputBoundary,
                "RuntimeFaultGate.InputBoundary",
                "MASRuntimeFaultStrictModeGate.vb",
                2,
                GetType(ArgumentException).FullName,
                "Synthetic input boundary probe.",
                2,
                False))

            records.Add(New MASRuntimeFaultRecord(
                nowUtc.AddMilliseconds(2),
                MASExceptionSeverity.CriticalStateTransition,
                MASExceptionHandlingCategory.LifecycleBreaking,
                "RuntimeFaultGate.Lifecycle",
                "MASRuntimeFaultStrictModeGate.vb",
                3,
                GetType(ApplicationException).FullName,
                "Synthetic lifecycle probe.",
                1,
                True))

            Dim snapshot As MASRuntimeFaultDeveloperPanelSnapshot = MASRuntimeFaultDeveloperPanelBuilder.CreateSnapshot(records, MASRuntimeFaultStrictnessSnapshot.FromCurrent())
            If snapshot Is Nothing Then
                findings.Add(New MASCommercialReadinessFinding("runtime-faults", "DeveloperPanel", MASCommercialReadinessFindingSeverity.Error, "Runtime fault developer panel snapshot could not be created."))
                Return
            End If

            If Not snapshot.ReadyForDeveloperDisplay Then
                findings.Add(New MASCommercialReadinessFinding("runtime-faults", "DeveloperPanel", MASCommercialReadinessFindingSeverity.Error, "Runtime fault developer panel snapshot is not ready for internal developer display."))
            End If

            If snapshot.TotalFaultCount <> 3 Then
                findings.Add(New MASCommercialReadinessFinding("runtime-faults", "FaultCount", MASCommercialReadinessFindingSeverity.Error, "Runtime fault developer panel did not preserve the expected fault count."))
            End If

            If snapshot.RecoverableCount <> 1 OrElse snapshot.BoundaryFailureCount <> 1 OrElse snapshot.CriticalStateTransitionCount <> 1 Then
                findings.Add(New MASCommercialReadinessFinding("runtime-faults", "SeveritySummary", MASCommercialReadinessFindingSeverity.Error, "Runtime fault developer panel did not summarize severities correctly."))
            End If

            If snapshot.RenderFallbackCount <> 1 OrElse snapshot.InputBoundaryCount <> 1 OrElse snapshot.LifecycleBreakingCount <> 1 Then
                findings.Add(New MASCommercialReadinessFinding("runtime-faults", "CategorySummary", MASCommercialReadinessFindingSeverity.Error, "Runtime fault developer panel did not summarize categories correctly."))
            End If

            If snapshot.RecentDiagnosticLines Is Nothing OrElse snapshot.RecentDiagnosticLines.Count = 0 OrElse String.IsNullOrWhiteSpace(snapshot.MostRecentDiagnosticLine) Then
                findings.Add(New MASCommercialReadinessFinding("runtime-faults", "DiagnosticLines", MASCommercialReadinessFindingSeverity.Error, "Runtime fault developer panel did not expose diagnostic lines for internal tooling."))
            End If
        End Sub

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

            Try
                Using scope As New MASRuntimeFaultStrictModeScope(True, False, True)
                    If scope Is Nothing OrElse Not scope.IsActive Then
                        findings.Add(New MASCommercialReadinessFinding("runtime-faults", "StrictScope", MASCommercialReadinessFindingSeverity.Error, "Runtime fault strict mode scope did not activate."))
                    End If

                    If Not MASExceptionSilencer.ThrowOnSwallowedException OrElse Not MASExceptionSilencer.TraceRepeatedBoundaryExceptions Then
                        findings.Add(New MASCommercialReadinessFinding("runtime-faults", "StrictSwitches", MASCommercialReadinessFindingSeverity.Error, "Runtime fault strict mode switches were not applied."))
                    End If

                    Try
                        MASExceptionSilencer.SwallowDiagnosticOnly(New InvalidOperationException("Strict mode probe."), "MASRuntimeFaultStrictModeGate.StrictProbe")
                    Catch ex As InvalidOperationException
                        strictModeThrew = ex.InnerException IsNot Nothing AndAlso TypeOf ex.InnerException Is InvalidOperationException
                    End Try
                End Using
            Catch ex As Exception
                MASExceptionSilencer.ConfigureStrictness(previousThrowOnAny, previousThrowOnLifecycle, previousTraceRepeated)
                findings.Add(New MASCommercialReadinessFinding("runtime-faults", "StrictScope", MASCommercialReadinessFindingSeverity.Error, "Runtime fault strict mode scope failed during validation: " & ex.GetType().FullName))
            End Try

            If Not strictModeThrew Then
                findings.Add(New MASCommercialReadinessFinding("runtime-faults", "StrictThrow", MASCommercialReadinessFindingSeverity.Error, "Runtime fault strict mode did not throw when a swallowed exception was attempted."))
            End If

            If MASExceptionSilencer.ThrowOnSwallowedException <> previousThrowOnAny OrElse
               MASExceptionSilencer.ThrowOnLifecycleBreakingException <> previousThrowOnLifecycle OrElse
               MASExceptionSilencer.TraceRepeatedBoundaryExceptions <> previousTraceRepeated Then
                MASExceptionSilencer.ConfigureStrictness(previousThrowOnAny, previousThrowOnLifecycle, previousTraceRepeated)
                findings.Add(New MASCommercialReadinessFinding("runtime-faults", "StrictRestore", MASCommercialReadinessFindingSeverity.Error, "Runtime fault strict mode scope did not restore the previous diagnostic switches."))
            End If
        End Sub

    End Class

End Namespace
