using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Protocol;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Alarms;
namespace ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Adapters;
/// Connection parameters resolved from the flat config dict.
public record MxGatewayConnectionOptions(
string Endpoint, string ApiKey, string ClientName, int WriteUserId,
bool UseTls, string? CaFile, string? ServerName, int ReadTimeoutMs,
// Maximum in-flight supervisory advise commands on the bulk-subscribe path when
// WriteUserId == 0 (the gateway worker has no BULK supervisory advise). Sourced from
// DataConnectionOptions.MxSupervisoryAdviseParallelism.
int SupervisoryAdviseParallelism = 16);
/// One advised-tag value change pushed from the gateway event stream.
public record MxValueUpdate(string TagPath, object? Value, QualityCode Quality, DateTimeOffset Timestamp);
/// Per-tag read outcome.
public record MxReadOutcome(string TagPath, bool Success, object? Value, QualityCode Quality, DateTimeOffset Timestamp, string? Error);
/// Per-tag write outcome.
public record MxWriteOutcome(string TagPath, bool Success, string? Error);
/// Per-tag outcome of a bulk subscribe (AddItem + Advise in one gateway command).
/// The requested tag address.
/// Whether the item was added and advised.
/// Gateway item handle (as a string) when successful.
/// Per-tag failure reason when not successful.
public record MxSubscribeOutcome(string TagPath, bool Success, string? SubscriptionId, string? Error);
/// One node in a Galaxy browse level.
public record MxBrowseChild(string NodeId, string DisplayName, BrowseNodeClass NodeClass, bool HasChildren, string? DataType = null);
///
/// Seam over the MxAccess Gateway .NET client + Galaxy repository client. Decouples
/// from the generated gRPC/protobuf types so the
/// adapter is unit-testable with a fake. The real implementation lives in
/// RealMxGatewayClient.
///
public interface IMxGatewayClient : IAsyncDisposable
{
/// Opens the gateway session and registers the client (Register → serverHandle held internally).
/// Resolved connection parameters.
/// Cancellation token.
/// A task that represents the asynchronous operation.
Task ConnectAsync(MxGatewayConnectionOptions options, CancellationToken ct = default);
/// Closes the session.
/// Cancellation token.
/// A task that represents the asynchronous operation.
Task DisconnectAsync(CancellationToken ct = default);
/// AddItem + Advise; returns the gateway item handle (as a string subscription id).
/// Tag address to subscribe to.
/// Cancellation token.
/// A task that resolves to the gateway item handle (subscription id).
Task SubscribeAsync(string tagPath, CancellationToken ct = default);
/// UnAdvise + RemoveItem for a previously returned subscription id.
/// Subscription id returned by .
/// Cancellation token.
/// A task that represents the asynchronous operation.
Task UnsubscribeAsync(string subscriptionId, CancellationToken ct = default);
///
/// Adds and advises MANY tags in as few gateway commands as the worker allows —
/// ONE SubscribeBulk round trip in plain-advise mode, or one
/// AddItemBulk plus bounded-parallel supervisory advises when the connection
/// has no write-user context (the worker has no bulk supervisory advise).
/// Replaces the historical 2-RPC-per-tag AddItem + Advise pair.
///
/// Tag addresses to subscribe.
/// Cancellation token.
/// One outcome per requested tag path, in request order.
Task> SubscribeBulkAsync(
IReadOnlyList tagPaths, CancellationToken ct = default);
/// UnAdvise + RemoveItem for many subscription ids in one gateway command.
/// Subscription ids previously returned by a subscribe call.
/// Cancellation token.
/// A task that represents the asynchronous operation.
Task UnsubscribeBulkAsync(IReadOnlyList subscriptionIds, CancellationToken ct = default);
/// Snapshot read of one or more tags (ReadBulk).
/// Tag addresses to read.
/// Cancellation token.
/// A task that resolves to one outcome per requested tag path.
Task> ReadAsync(IReadOnlyList tagPaths, CancellationToken ct = default);
/// Write one or more tag/value pairs (WriteBulk with the configured WriteUserId).
/// Tag/value pairs to write.
/// Cancellation token.
/// A task that resolves to one outcome per requested write.
Task> WriteAsync(IReadOnlyList<(string TagPath, object? Value)> writes, CancellationToken ct = default);
/// One Galaxy browse level (BrowseChildren). null → root.
/// Parent node id (Galaxy contained path), or null for root.
/// Cancellation token.
/// A task that resolves to the child nodes and a flag indicating whether the result was truncated.
Task<(IReadOnlyList Children, bool Truncated)> BrowseChildrenAsync(string? parentNodeId, CancellationToken ct = default);
///
/// Long-running event consumer. Invokes for each advised-tag
/// data change. Resumes from the last delivered worker sequence on reconnect. Completes
/// (or throws) when the stream ends — the adapter treats that as a disconnect.
///
/// Callback invoked per advised-tag value change.
/// Cancellation token; ends the loop when cancelled.
/// A task that represents the asynchronous operation.
Task RunEventLoopAsync(Action onUpdate, CancellationToken ct = default);
///
/// Long-running consumer of the gateway's session-less StreamAlarms feed. Emits a
/// Snapshot…SnapshotComplete replay of active alarms then live transitions. Re-opens
/// the stream internally on transport faults (the source replays a fresh snapshot).
/// Completes only when is cancelled.
///
/// Optional source-reference prefix to scope the feed; null = gateway-wide.
/// Callback invoked per native alarm transition.
/// Cancellation token; ends the loop when cancelled.
/// A task that represents the asynchronous operation.
Task RunAlarmStreamAsync(string? alarmFilterPrefix, Action onTransition, CancellationToken ct = default);
}
/// Builds instances.
public interface IMxGatewayClientFactory
{
/// Creates a new, unconnected client instance.
/// A new ready to be connected.
IMxGatewayClient Create();
}