using System;
using System.Collections.Generic;
namespace Svrnty.CQRS.Events.ConsumerGroups.Abstractions;
///
/// Configuration options for consumer group behavior.
///
public class ConsumerGroupOptions
{
///
/// Number of events to fetch in each batch from the stream.
/// Higher values improve throughput but increase memory usage.
/// Default: 100.
///
public int BatchSize { get; set; } = 100;
///
/// Polling interval when no events are available in the stream.
/// The consumer will sleep for this duration before checking for new events.
/// Default: 1 second.
///
public TimeSpan PollingInterval { get; set; } = TimeSpan.FromSeconds(1);
///
/// Offset commit strategy.
/// Determines when and how offsets are committed.
/// Default: AfterBatch.
///
public OffsetCommitStrategy CommitStrategy { get; set; } = OffsetCommitStrategy.AfterBatch;
///
/// Interval for periodic offset commits when using OffsetCommitStrategy.Periodic.
/// Ignored for other commit strategies.
/// Default: 5 seconds.
///
public TimeSpan PeriodicCommitInterval { get; set; } = TimeSpan.FromSeconds(5);
///
/// Heartbeat interval for consumer liveness.
/// The consumer will send heartbeats at this interval to signal it's alive.
/// Must be less than SessionTimeout.
/// Default: 10 seconds.
///
public TimeSpan HeartbeatInterval { get; set; } = TimeSpan.FromSeconds(10);
///
/// Consumer session timeout.
/// If a consumer doesn't send a heartbeat within this period, it's considered dead
/// and will be removed from the group.
/// Must be greater than HeartbeatInterval.
/// Default: 30 seconds.
///
public TimeSpan SessionTimeout { get; set; } = TimeSpan.FromSeconds(30);
///
/// Whether to start from the beginning of the stream if no offset has been committed.
/// If false, starts from the current end of the stream (only new events).
/// Default: true (start from beginning).
///
public bool StartFromBeginning { get; set; } = true;
///
/// Optional metadata to include with consumer registration.
/// Useful for debugging and monitoring (e.g., hostname, version, environment).
///
public IReadOnlyDictionary? Metadata { get; set; }
///
/// Validates the options and throws if invalid.
///
/// Thrown if options are invalid.
public void Validate()
{
if (BatchSize <= 0)
throw new ArgumentException("BatchSize must be greater than 0", nameof(BatchSize));
if (PollingInterval <= TimeSpan.Zero)
throw new ArgumentException("PollingInterval must be greater than 0", nameof(PollingInterval));
if (HeartbeatInterval <= TimeSpan.Zero)
throw new ArgumentException("HeartbeatInterval must be greater than 0", nameof(HeartbeatInterval));
if (SessionTimeout <= HeartbeatInterval)
throw new ArgumentException(
"SessionTimeout must be greater than HeartbeatInterval",
nameof(SessionTimeout));
if (CommitStrategy == OffsetCommitStrategy.Periodic && PeriodicCommitInterval <= TimeSpan.Zero)
throw new ArgumentException(
"PeriodicCommitInterval must be greater than 0 when using Periodic commit strategy",
nameof(PeriodicCommitInterval));
}
}