Option Strict On
Option Explicit On

Namespace Nexamas.UI.FloatRuntime

    ' ============================================================
    ' MASFloatRuntime Contract
    ' Class: MASFloatPolicyDecision
    '
    ' Purpose:
    '   Represents the result of a policy evaluation.
    '
    ' Responsibility:
    '   Carries whether an operation is allowed, which policy action was
    '   selected, and a human-readable reason for trace/debug.
    '
    ' Owns:
    '   Policy decision data only.
    '
    ' Does Not Own:
    '   Lifecycle execution.
    '   Queue mutation.
    '   Replacement execution.
    '   Host state.
    '   Result delivery.
    '
    ' Allowed Dependencies:
    '   MASFloatPolicyAction.
    '
    ' Forbidden Dependencies:
    '   Legacy Overlay classes.
    '   MASFloatCoordinator.
    '   MASFloatHost.
    '   MASFloatRuntimeState.
    '   Feature-owned lifecycle services.
    '
    ' Lifecycle Role:
    '   Produced by PolicyEngine and consumed by Coordinator.
    '
    ' Threading:
    '   Immutable-like decision object after creation by convention.
    '   Used on the UI/runtime lifecycle path.
    '
    ' Mutation Rules:
    '   Friend/internal code may create and populate decisions.
    '   External callers must not receive or mutate this object.
    '
    ' Invariants:
    '   Allowed=True must not be paired with Reject.
    '   Allowed=False should normally be paired with Reject.
    '   Reason must never be Nothing.
    '
    ' Failure Rules:
    '   Invalid combinations are normalized by factory helpers.
    ' ============================================================
    Friend NotInheritable Class MASFloatPolicyDecision

        Friend Property Allowed As Boolean

        Friend Property Action As MASFloatPolicyAction

        Friend Property Reason As String = String.Empty

        Friend Shared Function Allow(
            Optional reason As String = "Allowed."
        ) As MASFloatPolicyDecision
            Return New MASFloatPolicyDecision() With {
                .Allowed = True,
                .Action = MASFloatPolicyAction.Allow,
                .Reason = NormalizeReason(reason)
            }
        End Function

        Friend Shared Function Reject(reason As String) As MASFloatPolicyDecision
            Return New MASFloatPolicyDecision() With {
                .Allowed = False,
                .Action = MASFloatPolicyAction.Reject,
                .Reason = NormalizeReason(reason)
            }
        End Function

        Friend Shared Function Queue(reason As String) As MASFloatPolicyDecision
            Return New MASFloatPolicyDecision() With {
                .Allowed = True,
                .Action = MASFloatPolicyAction.Queue,
                .Reason = NormalizeReason(reason)
            }
        End Function

        Friend Shared Function Replace(reason As String) As MASFloatPolicyDecision
            Return New MASFloatPolicyDecision() With {
                .Allowed = True,
                .Action = MASFloatPolicyAction.Replace,
                .Reason = NormalizeReason(reason)
            }
        End Function

        Friend Shared Function CloseSameOwnerThenShow(reason As String) As MASFloatPolicyDecision
            Return New MASFloatPolicyDecision() With {
                .Allowed = True,
                .Action = MASFloatPolicyAction.CloseSameOwnerThenShow,
                .Reason = NormalizeReason(reason)
            }
        End Function

        Friend Shared Function Reuse(reason As String) As MASFloatPolicyDecision
            Return New MASFloatPolicyDecision() With {
                .Allowed = True,
                .Action = MASFloatPolicyAction.Reuse,
                .Reason = NormalizeReason(reason)
            }
        End Function

        Private Shared Function NormalizeReason(reason As String) As String
            If String.IsNullOrWhiteSpace(reason) Then
                Return String.Empty
            End If

            Return reason.Trim()
        End Function

    End Class

End Namespace