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

namespace ZB.MOM.WW.MxGateway.Server.Workers;

/// <summary>Manages communication with a single worker process via a named pipe.</summary>
public interface IWorkerClient : IAsyncDisposable
{
    /// <summary>Unique session identifier for this worker.</summary>
    string SessionId { get; }

    /// <summary>Process ID of the worker, or null before handshake completes.</summary>
    int? ProcessId { get; }

    /// <summary>Current state of the worker connection.</summary>
    WorkerClientState State { get; }

    /// <summary>UTC timestamp of the most recent heartbeat from the worker.</summary>
    DateTimeOffset LastHeartbeatAt { get; }

    /// <summary>Initiates the handshake and enters ready state.</summary>
    /// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task StartAsync(CancellationToken cancellationToken);

    /// <summary>Sends a command to the worker and waits for a reply.</summary>
    /// <param name="command">Worker command to invoke.</param>
    /// <param name="timeout">Timeout for waiting for the reply.</param>
    /// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
    /// <returns>The worker's reply to the command.</returns>
    Task<WorkerCommandReply> InvokeAsync(
        WorkerCommand command,
        TimeSpan timeout,
        CancellationToken cancellationToken);

    /// <summary>Reads events from the worker as they arrive.</summary>
    /// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
    /// <returns>An asynchronous stream of worker events.</returns>
    IAsyncEnumerable<WorkerEvent> ReadEventsAsync(CancellationToken cancellationToken);

    /// <summary>Gracefully shuts down the worker by closing the connection.</summary>
    /// <param name="timeout">Timeout for shutdown.</param>
    /// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task ShutdownAsync(TimeSpan timeout, CancellationToken cancellationToken);

    /// <summary>Terminates the worker process immediately with a diagnostic reason.</summary>
    /// <param name="reason">Reason for terminating the worker.</param>
    void Kill(string reason);
}
