using System;
using System.Collections.Generic;
using ZB.MOM.WW.MxGateway.Contracts.Proto;

namespace ZB.MOM.WW.MxGateway.Worker.MxAccess;

/// <summary>
///     Per-session interface routing the worker's alarm IPC commands —
///     <c>SubscribeAlarmsCommand</c>, <c>AcknowledgeAlarmCommand</c>,
///     <c>QueryActiveAlarmsCommand</c>, <c>UnsubscribeAlarmsCommand</c> —
///     to the underlying <see cref="AlarmDispatcher"/>. Production binding
///     is <see cref="AlarmCommandHandler"/>; tests substitute a fake.
/// </summary>
public interface IAlarmCommandHandler : IDisposable
{
    /// <summary>Begin a subscription against the supplied AVEVA alarm-provider expression.</summary>
    void Subscribe(string subscription, string sessionId);

    /// <summary>Tear down the active subscription. No-op if not subscribed.</summary>
    void Unsubscribe();

    /// <summary>Acknowledge a single alarm by GUID. Returns AVEVA's native status (0 = success).</summary>
    int Acknowledge(
        Guid alarmGuid,
        string comment,
        string operatorUser,
        string operatorNode,
        string operatorDomain,
        string operatorFullName);

    /// <summary>
    ///     Acknowledge a single alarm by (name, provider, group) — used when
    ///     the caller has the human-readable reference but not the GUID.
    /// </summary>
    int AcknowledgeByName(
        string alarmName,
        string providerName,
        string groupName,
        string comment,
        string operatorUser,
        string operatorNode,
        string operatorDomain,
        string operatorFullName);

    /// <summary>
    ///     Snapshot the currently-active alarm set, optionally scoped to a
    ///     prefix matched against <c>AlarmFullReference</c>.
    /// </summary>
    IReadOnlyList<ActiveAlarmSnapshot> QueryActive(string? alarmFilterPrefix);

    /// <summary>
    ///     Drives a single poll of the underlying alarm consumer on the
    ///     caller's thread. This is a no-op when there is no active
    ///     subscription. In production the caller is the worker's STA
    ///     (marshalled via <c>StaRuntime.InvokeAsync</c>), which satisfies
    ///     the <c>ThreadingModel=Apartment</c> requirement of
    ///     <c>wwAlarmConsumerClass</c>.
    /// </summary>
    void PollOnce();
}
