using System;
using Svrnty.CQRS.Events.Abstractions.EventStore;
using Svrnty.CQRS.Events.Abstractions.Models;
using Svrnty.CQRS.Events.Abstractions.Storage;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace Svrnty.CQRS.Events.Abstractions.Subscriptions;
///
/// Client interface for subscribing to event streams and consuming events.
///
///
///
/// This is the primary interface consumers use to receive events from subscriptions.
/// Supports async enumeration (IAsyncEnumerable) for streaming consumption.
///
///
/// Usage Pattern:
///
/// await foreach (var @event in client.SubscribeAsync("my-subscription", "consumer-1", ct))
/// {
/// // Process event
/// await ProcessEventAsync(@event);
///
/// // Event is automatically acknowledged after successful processing
/// // (unless manual acknowledgment mode is enabled)
/// }
///
///
///
public interface IEventSubscriptionClient
{
///
/// Subscribe to a subscription and receive events as an async stream.
///
/// The subscription ID to consume from.
/// Unique identifier for this consumer instance.
/// Cancellation token to stop consuming.
/// Async enumerable stream of events.
///
///
/// Events are automatically acknowledged after being yielded, unless manual acknowledgment is enabled.
/// The consumer is automatically registered when enumeration starts and unregistered when it stops.
///
///
/// Subscription Modes:
/// - Broadcast: Each consumer gets all events
/// - Exclusive: Only one consumer gets each event (load balanced)
/// - ConsumerGroup: Load balanced across group members
/// - ReadReceipt: Requires explicit MarkAsRead call
///
///
IAsyncEnumerable SubscribeAsync(
string subscriptionId,
string consumerId,
CancellationToken cancellationToken = default);
///
/// Subscribe with consumer metadata (hostname, version, etc.).
///
/// The subscription ID to consume from.
/// Unique identifier for this consumer instance.
/// Optional metadata about this consumer.
/// Cancellation token to stop consuming.
/// Async enumerable stream of events.
IAsyncEnumerable SubscribeAsync(
string subscriptionId,
string consumerId,
Dictionary metadata,
CancellationToken cancellationToken = default);
///
/// Manually acknowledge an event (only needed if manual acknowledgment mode is enabled).
///
/// The subscription ID.
/// The event ID to acknowledge.
/// The consumer ID acknowledging the event.
/// Cancellation token.
/// True if acknowledged, false if event not found or already acknowledged.
Task AcknowledgeAsync(
string subscriptionId,
string eventId,
string consumerId,
CancellationToken cancellationToken = default);
///
/// Negative acknowledge an event (NACK), marking it for redelivery or dead letter.
///
/// The subscription ID.
/// The event ID to NACK.
/// The consumer ID nacking the event.
/// If true, requeue for retry. If false, move to dead letter queue.
/// Cancellation token.
/// True if nacked, false if event not found.
Task NackAsync(
string subscriptionId,
string eventId,
string consumerId,
bool requeue = true,
CancellationToken cancellationToken = default);
///
/// Get subscription details.
///
/// The subscription ID.
/// Cancellation token.
/// The subscription configuration, or null if not found.
Task GetSubscriptionAsync(
string subscriptionId,
CancellationToken cancellationToken = default);
///
/// Get all active consumers for a subscription.
///
/// The subscription ID.
/// Cancellation token.
/// List of active consumer information.
Task> GetActiveConsumersAsync(
string subscriptionId,
CancellationToken cancellationToken = default);
///
/// Unsubscribe a consumer from a subscription.
///
/// The subscription ID.
/// The consumer ID to unregister.
/// Cancellation token.
/// True if unregistered, false if not found.
Task UnsubscribeAsync(
string subscriptionId,
string consumerId,
CancellationToken cancellationToken = default);
// ========================================================================
// Phase 3: Read Receipt API (Consumer Progress Tracking)
// ========================================================================
///
/// Records a read receipt for an event, tracking consumer progress.
///
/// The stream name.
/// The consumer identifier.
/// The event ID being acknowledged.
/// The event's offset/position in the stream.
/// Cancellation token.
///
///
/// Read receipts differ from acknowledgments:
/// - Acknowledgments are for subscription delivery tracking
/// - Read receipts are for consumer progress/offset tracking
///
///
/// Use this to track which events a consumer has successfully processed,
/// allowing resume from last position and monitoring consumer lag.
///
///
Task RecordReadReceiptAsync(
string streamName,
string consumerId,
string eventId,
long offset,
CancellationToken cancellationToken = default);
///
/// Gets the last acknowledged offset for a consumer on a stream.
///
/// The stream name.
/// The consumer identifier.
/// Cancellation token.
/// The last acknowledged offset, or null if no receipts exist.
Task GetLastReadOffsetAsync(
string streamName,
string consumerId,
CancellationToken cancellationToken = default);
///
/// Gets consumer progress statistics for a stream.
///
/// The stream name.
/// The consumer identifier.
/// Cancellation token.
/// Consumer progress information, or null if no receipts exist.
Task GetConsumerProgressAsync(
string streamName,
string consumerId,
CancellationToken cancellationToken = default);
///
/// Gets all consumers tracking a specific stream.
///
/// The stream name.
/// Cancellation token.
/// List of consumer IDs tracking this stream.
Task> GetStreamConsumersAsync(
string streamName,
CancellationToken cancellationToken = default);
}