Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports Nexamas.UI.Timing

Namespace Nexamas.UI.Quality

    ''' <summary>
    ''' Friend-only gate that proves MAS time/motion ownership is centralized enough
    ''' for deterministic diagnostics without turning every approved host/input timer
    ''' into a false production blocker.
    ''' </summary>
    Friend NotInheritable Class MASTimeMotionOwnershipGate

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

            ValidateManifest(findings)
            ValidateProviderScope(findings)
            ValidateVisualClock(findings)
            ValidateInteractionClock(findings)

            Return findings
        End Function

        Private Shared Sub ValidateManifest(findings As List(Of MASCommercialReadinessFinding))
            Dim manifest As MASTimeMotionOwnershipManifest = Nothing

            Try
                manifest = MASTimeMotionOwnershipManifest.CreateDefault()
            Catch ex As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowDiagnosticOnly(ex, "MASTimeMotionOwnershipGate.CreateManifest")
                findings.Add(New MASCommercialReadinessFinding("time-motion", "Manifest", MASCommercialReadinessFindingSeverity.Error, "Time/motion ownership manifest could not be built."))
                Return
            End Try

            If manifest Is Nothing OrElse Not manifest.HasRequiredOwnershipCoverage Then
                findings.Add(New MASCommercialReadinessFinding("time-motion", "Coverage", MASCommercialReadinessFindingSeverity.Error, "Time/motion ownership manifest does not cover the required central clocks and approved scheduling exceptions."))
                Return
            End If

            Dim ids As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
            For Each record As MASTimeMotionOwnershipRecord In manifest.Records
                If record Is Nothing Then
                    findings.Add(New MASCommercialReadinessFinding("time-motion", "Record", MASCommercialReadinessFindingSeverity.Error, "Time/motion ownership manifest contains a null record."))
                    Continue For
                End If

                If Not ids.Add(record.OwnerId) Then
                    findings.Add(New MASCommercialReadinessFinding(record.OwnerId, "DuplicateId", MASCommercialReadinessFindingSeverity.Error, "Time/motion ownership id is duplicated."))
                End If

                If Not record.IsStructurallyValid Then
                    findings.Add(New MASCommercialReadinessFinding(record.OwnerId, "Structure", MASCommercialReadinessFindingSeverity.Error, record.DisplayName & " has an invalid time/motion ownership declaration."))
                End If
            Next
        End Sub

        Private Shared Sub ValidateProviderScope(findings As List(Of MASCommercialReadinessFinding))
            Dim previous As MASTimeProviderSnapshot = MASTimeProvider.CaptureSnapshot()
            Dim fixedLocal As New DateTime(2026, 7, 3, 12, 0, 0, DateTimeKind.Local)
            Dim fixedUtc As New DateTime(2026, 7, 3, 10, 0, 0, DateTimeKind.Utc)

            Try
                Using scope As New MASTimeProviderScope(fixedLocal, fixedUtc, 12345, 987654321L)
                    If scope Is Nothing OrElse Not scope.IsActive Then
                        findings.Add(New MASCommercialReadinessFinding("time-motion", "ProviderScope", MASCommercialReadinessFindingSeverity.Error, "MASTimeProvider diagnostic scope did not activate."))
                    End If

                    Dim snap As MASTimeProviderSnapshot = MASTimeProvider.CaptureSnapshot()
                    If snap Is Nothing OrElse Not snap.IsStructurallyValid OrElse Not snap.HasDiagnosticOverride Then
                        findings.Add(New MASCommercialReadinessFinding("time-motion", "ProviderSnapshot", MASCommercialReadinessFindingSeverity.Error, "MASTimeProvider snapshot did not report a valid deterministic override."))
                    End If

                    If MASTimeProvider.LocalNow() <> fixedLocal OrElse MASTimeProvider.UtcNow() <> fixedUtc OrElse MASTimeProvider.TickCount() <> 12345 OrElse MASTimeProvider.Timestamp() <> 987654321L Then
                        findings.Add(New MASCommercialReadinessFinding("time-motion", "ProviderValues", MASCommercialReadinessFindingSeverity.Error, "MASTimeProvider did not return the deterministic diagnostic values."))
                    End If
                End Using
            Catch ex As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowDiagnosticOnly(ex, "MASTimeMotionOwnershipGate.ProviderScope")
                findings.Add(New MASCommercialReadinessFinding("time-motion", "ProviderScope", MASCommercialReadinessFindingSeverity.Error, "MASTimeProvider diagnostic scope failed during validation."))
            End Try

            If MASTimeProvider.HasDiagnosticOverride() Then
                findings.Add(New MASCommercialReadinessFinding("time-motion", "ProviderRestore", MASCommercialReadinessFindingSeverity.Error, "MASTimeProvider diagnostic scope did not restore the previous provider state."))
            End If

            If previous Is Nothing OrElse Not previous.IsStructurallyValid Then
                findings.Add(New MASCommercialReadinessFinding("time-motion", "ProviderBaseline", MASCommercialReadinessFindingSeverity.Error, "MASTimeProvider baseline snapshot is invalid."))
            End If
        End Sub

        Private Shared Sub ValidateVisualClock(findings As List(Of MASCommercialReadinessFinding))
            Dim delta As Integer = MASVisualClock.TimestampDeltaMilliseconds(1000L, 1000L + CInt(Math.Max(1L, MASTimeProvider.TimestampFrequency \ 60L)))
            If delta <= 0 OrElse delta > 64 Then
                findings.Add(New MASCommercialReadinessFinding("time-motion", "VisualDelta", MASCommercialReadinessFindingSeverity.Error, "MASVisualClock did not produce a bounded frame delta."))
            End If

            If MASVisualClock.NormalizeFrameDeltaMs(-1) <> 0 OrElse MASVisualClock.NormalizeFrameDeltaMs(1200) <> 1000 Then
                findings.Add(New MASCommercialReadinessFinding("time-motion", "VisualNormalize", MASCommercialReadinessFindingSeverity.Error, "MASVisualClock frame delta normalization is invalid."))
            End If

            If MASVisualClock.NormalizeVisualPulseIntervalMs(0) <> 1 OrElse MASVisualClock.NormalizeVisualPulseIntervalMs(5000) <> 1000 Then
                findings.Add(New MASCommercialReadinessFinding("time-motion", "VisualPulse", MASCommercialReadinessFindingSeverity.Error, "MASVisualClock visual pulse interval normalization is invalid."))
            End If
        End Sub

        Private Shared Sub ValidateInteractionClock(findings As List(Of MASCommercialReadinessFinding))
            Dim elapsed As Integer = MASInteractionClock.ElapsedMilliseconds(100, 250)
            If elapsed <> 150 Then
                findings.Add(New MASCommercialReadinessFinding("time-motion", "InteractionElapsed", MASCommercialReadinessFindingSeverity.Error, "MASInteractionClock elapsed tick calculation is invalid."))
            End If

            Using scope As New MASTimeProviderScope(New DateTime(2026, 7, 3, 12, 0, 0), New DateTime(2026, 7, 3, 10, 0, 0, DateTimeKind.Utc), 200, 10000L)
                If Not MASInteractionClock.IsWithinWindow(50, 200) Then
                    findings.Add(New MASCommercialReadinessFinding("time-motion", "InteractionWindow", MASCommercialReadinessFindingSeverity.Error, "MASInteractionClock did not evaluate a deterministic interaction window correctly."))
                End If
            End Using
        End Sub

    End Class

End Namespace
