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

namespace ZB.MOM.WW.MxGateway.Client.Cli;

/// <summary>
///     Transport seam used by the CLI to drive gateway and Galaxy Repository
///     RPCs, exposing only the operations the command surface needs. The
///     production binding is <see cref="MxGatewayCliClientAdapter"/> (wrapping a
///     real <c>MxGatewayClient</c>); tests substitute an in-memory fake so the
///     command routing can be exercised without a live gateway.
/// </summary>
public interface IMxGatewayCliClient : IAsyncDisposable
{
    /// <summary>
    /// Opens a new gateway session.
    /// </summary>
    /// <param name="request">Session open request.</param>
    /// <param name="cancellationToken">Cancellation token for the operation.</param>
    /// <returns>The session open reply.</returns>
    Task<OpenSessionReply> OpenSessionAsync(
        OpenSessionRequest request,
        CancellationToken cancellationToken);

    /// <summary>
    /// Closes an open gateway session.
    /// </summary>
    /// <param name="request">Session close request.</param>
    /// <param name="cancellationToken">Cancellation token for the operation.</param>
    /// <returns>The session close reply.</returns>
    Task<CloseSessionReply> CloseSessionAsync(
        CloseSessionRequest request,
        CancellationToken cancellationToken);

    /// <summary>
    /// Invokes an MXAccess command on the session.
    /// </summary>
    /// <param name="request">The command request.</param>
    /// <param name="cancellationToken">Cancellation token for the operation.</param>
    /// <returns>The command reply.</returns>
    Task<MxCommandReply> InvokeAsync(
        MxCommandRequest request,
        CancellationToken cancellationToken);

    /// <summary>
    /// Streams events from the gateway session.
    /// </summary>
    /// <param name="request">The stream events request.</param>
    /// <param name="cancellationToken">Cancellation token for the operation.</param>
    /// <returns>An async enumerable of events.</returns>
    IAsyncEnumerable<MxEvent> StreamEventsAsync(
        StreamEventsRequest request,
        CancellationToken cancellationToken);

    /// <summary>
    /// Acknowledges an active MXAccess alarm condition through the gateway.
    /// </summary>
    /// <param name="request">The acknowledge request — alarm reference, comment, operator user.</param>
    /// <param name="cancellationToken">Cancellation token for the operation.</param>
    /// <returns>The acknowledge reply with protocol + native MxStatus.</returns>
    Task<AcknowledgeAlarmReply> AcknowledgeAlarmAsync(
        AcknowledgeAlarmRequest request,
        CancellationToken cancellationToken);

    /// <summary>
    /// Attaches to the gateway's central alarm feed — the current active-alarm
    /// snapshot followed by live transitions.
    /// </summary>
    /// <param name="request">The stream request, optionally scoped by alarm-reference prefix.</param>
    /// <param name="cancellationToken">Cancellation token for the operation.</param>
    /// <returns>An async enumerable of alarm feed messages.</returns>
    IAsyncEnumerable<AlarmFeedMessage> StreamAlarmsAsync(
        StreamAlarmsRequest request,
        CancellationToken cancellationToken);

    /// <summary>
    /// Tests connection to the Galaxy Repository.
    /// </summary>
    /// <param name="request">The connection test request.</param>
    /// <param name="cancellationToken">Cancellation token for the operation.</param>
    /// <returns>The connection test reply.</returns>
    Task<TestConnectionReply> GalaxyTestConnectionAsync(
        TestConnectionRequest request,
        CancellationToken cancellationToken);

    /// <summary>
    /// Gets the last deployment time from the Galaxy Repository.
    /// </summary>
    /// <param name="request">The last deploy time request.</param>
    /// <param name="cancellationToken">Cancellation token for the operation.</param>
    /// <returns>The last deploy time reply.</returns>
    Task<GetLastDeployTimeReply> GalaxyGetLastDeployTimeAsync(
        GetLastDeployTimeRequest request,
        CancellationToken cancellationToken);

    /// <summary>
    /// Discovers the Galaxy Repository hierarchy.
    /// </summary>
    /// <param name="request">The discover hierarchy request.</param>
    /// <param name="cancellationToken">Cancellation token for the operation.</param>
    /// <returns>The discover hierarchy reply.</returns>
    Task<DiscoverHierarchyReply> GalaxyDiscoverHierarchyAsync(
        DiscoverHierarchyRequest request,
        CancellationToken cancellationToken);

    /// <summary>
    /// Watches for deployment events from the Galaxy Repository.
    /// </summary>
    /// <param name="request">The watch deploy events request.</param>
    /// <param name="cancellationToken">Cancellation token for the operation.</param>
    /// <returns>An async enumerable of deployment events.</returns>
    IAsyncEnumerable<DeployEvent> GalaxyWatchDeployEventsAsync(
        WatchDeployEventsRequest request,
        CancellationToken cancellationToken);

    /// <summary>
    /// Fetches one page of direct children of a Galaxy parent (or the root
    /// objects when the parent selector is unset), the primitive that backs the
    /// lazy-browse helper.
    /// </summary>
    /// <param name="request">The browse-children request.</param>
    /// <param name="cancellationToken">Cancellation token for the operation.</param>
    /// <returns>The browse-children reply.</returns>
    Task<BrowseChildrenReply> GalaxyBrowseChildrenAsync(
        BrowseChildrenRequest request,
        CancellationToken cancellationToken);
}
