namespace ZB.MOM.WW.LocalDb.Replication;

/// <summary>
/// Configuration for the bidirectional 2-node replication engine. All durations are wall-clock UTC.
/// </summary>
public sealed class ReplicationOptions
{
    /// <summary>gRPC address of the peer to dial. Required for the initiator role (validated in the sync host).</summary>
    public string PeerAddress { get; set; } = "";

    /// <summary>API key presented to / expected from the peer; null disables key auth.</summary>
    public string? ApiKey { get; set; }

    /// <summary>How often the change pump flushes pending oplog deltas to the peer.</summary>
    public TimeSpan FlushInterval { get; set; } = TimeSpan.FromMilliseconds(250);

    /// <summary>Maximum oplog entries sent per outbound batch.</summary>
    public int MaxBatchSize { get; set; } = 500;

    /// <summary>Backlog ceiling: exceeding it flags a snapshot resync and prunes the oldest oplog rows.</summary>
    public long MaxOplogRows { get; set; } = 1_000_000;

    /// <summary>Age ceiling: an unpruned oplog entry older than this flags a snapshot resync.</summary>
    public TimeSpan MaxOplogAge { get; set; } = TimeSpan.FromDays(7);

    /// <summary>How long deleted-row tombstones are retained before pruning.</summary>
    public TimeSpan TombstoneRetention { get; set; } = TimeSpan.FromDays(7);

    /// <summary>Upper bound on the exponential reconnect backoff.</summary>
    public TimeSpan ReconnectBackoffMax { get; set; } = TimeSpan.FromSeconds(60);

    /// <summary>How often the maintenance service enforces the oplog caps and prunes expired tombstones.</summary>
    public TimeSpan MaintenanceInterval { get; set; } = TimeSpan.FromSeconds(60);

    /// <summary>Maximum tolerated HLC drift where a peer's clock runs ahead of ours.</summary>
    public TimeSpan MaxHlcDriftAhead { get; set; } = TimeSpan.FromMinutes(5);

    /// <summary>
    /// When true, entries whose HLC physical time exceeds <see cref="MaxHlcDriftAhead"/> are
    /// dead-lettered individually (the rest of the batch still applies); when false, drifted
    /// entries are applied and a single warning is logged per session.
    /// </summary>
    public bool FailClosedOnDrift { get; set; }
}
