using System;
using System.Collections.Generic;
namespace ZB.MOM.WW.MxGateway.Worker.MxAccess;
///
/// Abstraction over an AVEVA alarm-consumer COM library. The production
/// implementation () wraps
/// WNWRAPCONSUMERLib.wwAlarmConsumerClass from
/// C:\Program Files (x86)\Common Files\ArchestrA\wnwrapConsumer.dll;
/// tests substitute a fake to drive transition events without a live
/// Galaxy.
///
///
///
/// The receive surface is poll-based: the production consumer
/// periodically calls GetXmlCurrentAlarms2, parses the
/// returned XML payload, diffs against the previous snapshot keyed
/// by alarm GUID, and raises
/// once per state change. This bypasses the FILETIME marshaling
/// crash in aaAlarmManagedClient.AlarmClient.GetHighPriAlarm
/// (see docs/AlarmClientDiscovery.md) — XML strings carry
/// timestamps as ASCII fields, no DateTime auto-conversion happens
/// on the .NET interop boundary.
///
///
public interface IMxAccessAlarmConsumer : IDisposable
{
///
/// Fires once per detected alarm-state transition (raise, acknowledge,
/// clear, or new-alarm-already-acked-on-arrival). Subscribers are
/// expected to translate the record into the proto family
/// OnAlarmTransition and enqueue it. Fired on the consumer's
/// polling thread (the worker's STA in production); subscribers that
/// need a different thread must marshal back themselves.
///
event EventHandler? AlarmTransitionEmitted;
///
/// Initializes the AVEVA alarm-client connection, registers as a
/// consumer, and subscribes to the supplied alarm-provider expression.
/// Subscription string follows AVEVA's canonical format:
/// \\<node>\Galaxy!<area>. The literal "Galaxy" is
/// the provider name (regardless of the configured Galaxy database
/// name). Subscribe does not start any polling of its own; the caller
/// drives polls explicitly via .
///
/// The subscription expression (e.g., \\HOST\Galaxy!Area).
void Subscribe(string subscription);
///
/// Resolves the MXAccess item whose write acknowledges the alarm with the
/// given GUID (e.g. Obj.Alarm.AckMsg). Does not perform the ack.
///
/// The alarm GUID as reported by this consumer.
/// The resolved target or the reason none exists.
AlarmAckTarget ResolveAckTarget(Guid alarmGuid);
/// Resolves the ack item for an alarm identified by name, provider and group.
/// The tag/alarm name, e.g. TestMachine_001.TestAlarm001.
/// The provider (literal Galaxy for ArchestrA).
/// The area/group.
/// The resolved target or the reason none exists.
AlarmAckTarget ResolveAckTargetByName(string alarmName, string providerName, string groupName);
///
/// Returns the consumer's most recently parsed snapshot of currently
/// active alarms, together with whether the fetch that produced it hit
/// the per-fetch cap. Used by the gateway's QueryActiveAlarms (PR A.7)
/// ConditionRefresh path — operator clients call this after reconnect
/// to seed local Part 9 state.
///
///
///
/// The verdict is an out parameter rather than a separate
/// property on purpose, and the reason is a correctness one.
/// Implementations must produce both values from a single acquisition
/// of whatever lock guards the retained snapshot, mirroring the write
/// side (WnWrapAlarmConsumer.FoldFetch updates snapshot and
/// verdict together). Two separate reads could straddle a poll that
/// flips not-truncated → truncated and pair a stale
/// with a capped snapshot — a snapshot that
/// reads as complete while missing actives, which is exactly the
/// false all-clear this signal exists to prevent. Making the pair
/// inseparable in the signature removes the possibility rather than
/// relying on callers, or on the STA serializing them.
///
///
/// While is the
/// returned snapshot is authoritative about presence only: the
/// provider may hold actives it had no room to report, and the
/// consumer has suspended the absence-implies-Clear inference. Not
/// latched — the first sub-cap fetch clears it, because that fetch is
/// complete and its snapshot is again authoritative about absence.
/// Consumers with no per-fetch cap (the subtag fallback, which is
/// advise-driven) always report .
///
///
///
/// Receives whether the fetch behind the returned snapshot hit the
/// per-fetch cap.
///
/// The most recently parsed snapshot of currently active alarms.
IReadOnlyList SnapshotActiveAlarms(out bool truncated);
///
/// Drives a single synchronous poll of the underlying alarm source.
/// The production consumer owns no internal timer; the worker's STA
/// drives polls via StaRuntime.InvokeAsync, satisfying the
/// ThreadingModel=Apartment requirement of
/// wwAlarmConsumerClass. Fake implementations should no-op.
/// This method must be invoked on the thread that created the consumer
/// (the worker's STA in production).
///
void PollOnce();
}