using ZB.MOM.WW.MxGateway.Contracts.Proto;

namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Runtime;

/// <summary>
///     Driver-side seam for subscription lifecycle + the inbound event stream. Production
///     wraps <c>MxGatewaySession.SubscribeBulkAsync</c>, <c>UnsubscribeBulkAsync</c>, and
///     <c>StreamEventsAsync</c>; tests substitute a fake to drive synthetic events through
///     the <see cref="EventPump"/> without a real gw.
/// </summary>
public interface IGalaxySubscriber
{
    /// <summary>
    ///     Subscribe a batch of tag full references. Returns one
    ///     <see cref="SubscribeResult"/> per request entry, in input order. Failed tags
    ///     (gateway rejection) carry a non-zero status and an item handle of zero or
    ///     negative — the caller treats those as per-tag failures rather than a whole-call
    ///     failure.
    /// </summary>
    /// <param name="fullReferences">The list of tag references to subscribe to.</param>
    /// <param name="bufferedUpdateIntervalMs">The buffered update interval in milliseconds.</param>
    /// <param name="cancellationToken">Cancellation token for the operation.</param>
    /// <returns>One <see cref="SubscribeResult"/> per requested reference, in input order.</returns>
    Task<IReadOnlyList<SubscribeResult>> SubscribeBulkAsync(
        IReadOnlyList<string> fullReferences, int bufferedUpdateIntervalMs, CancellationToken cancellationToken);

    /// <summary>Unsubscribe a batch of item handles obtained from <see cref="SubscribeBulkAsync"/>.</summary>
    /// <param name="itemHandles">The item handles to unsubscribe.</param>
    /// <param name="cancellationToken">Cancellation token for the operation.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task UnsubscribeBulkAsync(IReadOnlyList<int> itemHandles, CancellationToken cancellationToken);

    /// <summary>
    ///     Long-running consumer of the gateway's <c>StreamEvents</c> RPC. Each emitted
    ///     <see cref="MxEvent"/> carries the gw item handle the caller correlates against
    ///     its <see cref="SubscriptionRegistry"/>.
    /// </summary>
    /// <param name="cancellationToken">Cancellation token for the stream.</param>
    /// <returns>An asynchronous stream of <see cref="MxEvent"/>s as they arrive from the gateway.</returns>
    IAsyncEnumerable<MxEvent> StreamEventsAsync(CancellationToken cancellationToken);
}
