using System;
using System.Collections.Generic;
using Svrnty.CQRS.Events.Abstractions.Subscriptions;
namespace Svrnty.CQRS.Events.Abstractions.Models;
///
/// Represents a client's subscription to events for a specific correlation.
///
public sealed class EventSubscription
{
///
/// Unique identifier for this subscription.
///
public required string SubscriptionId { get; init; }
///
/// ID of the user/client that created this subscription.
///
public required string SubscriberId { get; init; }
///
/// Correlation ID this subscription is listening to.
///
public required string CorrelationId { get; init; }
///
/// Event type names the subscriber wants to receive (e.g., "UserInvitationSentEvent").
/// Empty set means all event types.
///
public required HashSet EventTypes { get; init; }
///
/// Event types that will complete/close this subscription when received.
///
public HashSet TerminalEventTypes { get; init; } = new();
///
/// How events should be delivered to the subscriber.
///
public DeliveryMode DeliveryMode { get; init; } = DeliveryMode.Immediate;
///
/// When this subscription was created.
///
public DateTimeOffset CreatedAt { get; init; }
///
/// Optional expiration time for this subscription.
///
public DateTimeOffset? ExpiresAt { get; init; }
///
/// When this subscription was completed (terminal event or cancellation).
///
public DateTimeOffset? CompletedAt { get; set; }
///
/// Last successfully delivered event sequence number (for catch-up).
///
public long LastDeliveredSequence { get; set; }
///
/// Current status of this subscription.
///
public SubscriptionStatus Status { get; set; } = SubscriptionStatus.Active;
///
/// Checks if this subscription is expired.
///
public bool IsExpired => ExpiresAt.HasValue && DateTimeOffset.UtcNow > ExpiresAt.Value;
///
/// Checks if this subscription should receive the specified event type.
///
public bool ShouldReceive(string eventType)
{
return EventTypes.Count == 0 || EventTypes.Contains(eventType);
}
///
/// Checks if the specified event type is a terminal event for this subscription.
///
public bool IsTerminalEvent(string eventType)
{
return TerminalEventTypes.Contains(eventType);
}
}