using ZB.MOM.WW.CBDD.Core.Transactions;

namespace ZB.MOM.WW.CBDD.Core.CDC;

/// <summary>
///     A generic, immutable struct representing a data change in a collection.
/// </summary>
public readonly struct ChangeStreamEvent<TId, T> where T : class
{
    /// <summary>
    ///     Gets the UTC timestamp when the change was recorded.
    /// </summary>
    public long Timestamp { get; init; }

    /// <summary>
    ///     Gets the transaction identifier that produced the change.
    /// </summary>
    public ulong TransactionId { get; init; }

    /// <summary>
    ///     Gets the collection name where the change occurred.
    /// </summary>
    public string CollectionName { get; init; }

    /// <summary>
    ///     Gets the operation type associated with the change.
    /// </summary>
    public OperationType Type { get; init; }

    /// <summary>
    ///     Gets the changed document identifier.
    /// </summary>
    public TId DocumentId { get; init; }

    /// <summary>
    ///     The deserialized entity. Null if capturePayload was false during Watch().
    /// </summary>
    public T? Entity { get; init; }
}

/// <summary>
///     Low-level event structure used internally to transport changes before deserialization.
/// </summary>
internal readonly struct InternalChangeEvent
{
    /// <summary>
    ///     Gets the UTC timestamp when the change was recorded.
    /// </summary>
    public long Timestamp { get; init; }

    /// <summary>
    ///     Gets the transaction identifier that produced the change.
    /// </summary>
    public ulong TransactionId { get; init; }

    /// <summary>
    ///     Gets the collection name where the change occurred.
    /// </summary>
    public string CollectionName { get; init; }

    /// <summary>
    ///     Gets the operation type associated with the change.
    /// </summary>
    public OperationType Type { get; init; }

    /// <summary>
    ///     Raw BSON of the Document ID.
    /// </summary>
    public ReadOnlyMemory<byte> IdBytes { get; init; }

    /// <summary>
    ///     Raw BSON of the Entity. Null if payload not captured.
    /// </summary>
    public ReadOnlyMemory<byte>? PayloadBytes { get; init; }
}