using ZB.MOM.WW.LmxProxy.Client.Domain;

namespace ScadaLink.DataConnectionLayer.Adapters;

/// <summary>
/// Subscription handle returned by <see cref="ILmxProxyClient.SubscribeAsync"/>.
/// Disposing the subscription stops receiving updates.
/// </summary>
public interface ILmxSubscription : IAsyncDisposable { }

/// <summary>
/// Abstraction over the LmxProxy SDK client for testability.
/// The production implementation delegates to the real
/// <see cref="ZB.MOM.WW.LmxProxy.Client.LmxProxyClient"/> library.
/// </summary>
public interface ILmxProxyClient : IAsyncDisposable
{
    bool IsConnected { get; }

    Task ConnectAsync(CancellationToken cancellationToken = default);
    Task DisconnectAsync();

    Task<Vtq> ReadAsync(string address, CancellationToken cancellationToken = default);
    Task<IDictionary<string, Vtq>> ReadBatchAsync(IEnumerable<string> addresses, CancellationToken cancellationToken = default);

    Task WriteAsync(string address, TypedValue value, CancellationToken cancellationToken = default);
    Task WriteBatchAsync(IDictionary<string, TypedValue> values, CancellationToken cancellationToken = default);

    Task<ILmxSubscription> SubscribeAsync(
        IEnumerable<string> addresses,
        Action<string, Vtq> onUpdate,
        Action<Exception>? onStreamError = null,
        CancellationToken cancellationToken = default);
}

/// <summary>
/// Factory for creating <see cref="ILmxProxyClient"/> instances configured
/// with host, port, and optional API key.
/// </summary>
public interface ILmxProxyClientFactory
{
    ILmxProxyClient Create(string host, int port, string? apiKey, bool useTls = false);
}
