Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Motion

Namespace Nexamas.UI.Quality

    ''' <summary>
    ''' Runtime proof for live reduced-motion policy mutation while a Motion runner is active.
    ''' Active runners keep their immutable plan; newly created plans immediately honor the new policy,
    ''' and host-clock registration remains balanced.
    ''' </summary>
    Friend NotInheritable Class MASReducedMotionMutationDuringAnimationGate

        Private Sub New()
        End Sub

        Friend Shared Function Passes() As Boolean
            Dim previousMode As MASMotionReducedMotionMode = MASMotionSystem.ReducedMotionMode

            Try
                Return ProbeActiveRunnerSurvivesPolicyMutation() AndAlso
                       ProbeNewPlansHonorMutationImmediately()
            Catch ex As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowDiagnosticOnly(ex, "MASReducedMotionMutationDuringAnimationGate")
                Return False
            Finally
                MASMotionSystem.ReducedMotionMode = previousMode
            End Try
        End Function

        Private Shared Function ProbeActiveRunnerSurvivesPolicyMutation() As Boolean
            MASMotionSystem.ReducedMotionMode = MASMotionReducedMotionMode.FullMotion

            Using clock As New MASMotionFrameClock("reduced-motion-active-runner")
                Dim owner As New Object()
                Dim applyCount As Integer = 0
                Dim requestCount As Integer = 0
                Dim completedCount As Integer = 0
                Dim lastFrame As MASMotionFrame = Nothing
                Dim runner As MASMotionTimelineRunner = Nothing

                Try
                    Dim plan As MASMotionTransitionPlan =
                        MASMotionSystem.CreateTransitionPlan(MASMotionTokenId.RowSelectionMove, 0.0F, 1.0F, 600000, MASMotionEasing.Linear)

                    If Not plan.ShouldAnimate Then Return False

                    runner = MASMotionSystem.CreateTimelineRunner(
                        owner:=owner,
                        consumerName:="reduced-motion-active-runner",
                        plan:=plan,
                        requestFrame:=Sub()
                                          requestCount += 1
                                      End Sub,
                        applyFrame:=Sub(frame As MASMotionFrame)
                                        applyCount += 1
                                        lastFrame = frame
                                    End Sub,
                        completed:=Sub(frame As MASMotionFrame)
                                       completedCount += 1
                                   End Sub,
                        motionFrameClock:=clock)

                    runner.Start()

                    If applyCount <> 1 Then Return False
                    If requestCount <> 1 Then Return False
                    If clock.ActiveConsumerCount() <> 1 Then Return False

                    MASMotionSystem.ReducedMotionMode = MASMotionReducedMotionMode.DisableNonEssentialMotion

                    Dim reducedPlan As MASMotionTransitionPlan =
                        MASMotionSystem.CreateTransitionPlan(MASMotionTokenId.RowSelectionMove, 0.0F, 1.0F)

                    If reducedPlan.ShouldAnimate Then Return False
                    If reducedPlan.EffectiveDurationMs <> 0 Then Return False

                    If Not clock.AdvanceScheduledAnimations() Then Return False

                    If applyCount <= 1 Then Return False
                    If requestCount <= 1 Then Return False
                    If completedCount <> 0 Then Return False
                    If lastFrame Is Nothing Then Return False
                    If lastFrame.DurationMs <> plan.EffectiveDurationMs Then Return False
                    If clock.ActiveConsumerCount() <> 1 Then Return False

                    runner.Dispose()
                    runner = Nothing

                    Return clock.ActiveConsumerCount() = 0
                Finally
                    If runner IsNot Nothing Then runner.Dispose()
                End Try
            End Using
        End Function

        Private Shared Function ProbeNewPlansHonorMutationImmediately() As Boolean
            MASMotionSystem.ReducedMotionMode = MASMotionReducedMotionMode.PreferReducedMotion
            Dim preferredPlan As MASMotionTransitionPlan =
                MASMotionSystem.CreateTransitionPlan(MASMotionTokenId.RowSelectionMove, 0.0F, 1.0F)

            If Not preferredPlan.ShouldAnimate Then Return False
            If preferredPlan.EffectiveDurationMs > 60 Then Return False

            MASMotionSystem.ReducedMotionMode = MASMotionReducedMotionMode.DisableNonEssentialMotion
            Dim disabledPlan As MASMotionTransitionPlan =
                MASMotionSystem.CreateTransitionPlan(MASMotionTokenId.RowSelectionMove, 0.0F, 1.0F)

            If disabledPlan.ShouldAnimate Then Return False
            If disabledPlan.EffectiveDurationMs <> 0 Then Return False

            MASMotionSystem.ReducedMotionMode = MASMotionReducedMotionMode.FullMotion
            Dim fullPlan As MASMotionTransitionPlan =
                MASMotionSystem.CreateTransitionPlan(MASMotionTokenId.RowSelectionMove, 0.0F, 1.0F)

            Return fullPlan.ShouldAnimate AndAlso fullPlan.EffectiveDurationMs > preferredPlan.EffectiveDurationMs
        End Function

    End Class

End Namespace
