package mxgateway

import (
	"context"
	"errors"
)

// AcknowledgeAlarm acknowledges an active MXAccess alarm condition through the
// gateway. The gateway authenticates the request against the API key's
// invoke:alarm-ack scope and forwards the acknowledge to the worker's MXAccess
// session; the resulting native MxStatus is returned in the reply.
//
// Acks are idempotent — re-acking an already-acked condition is a no-op at
// the MxAccess layer.
func (c *Client) AcknowledgeAlarm(ctx context.Context, req *AcknowledgeAlarmRequest) (*AcknowledgeAlarmReply, error) {
	if req == nil {
		return nil, errors.New("mxgateway: acknowledge alarm request is required")
	}

	callCtx, cancel := c.callContext(ctx)
	defer cancel()

	reply, err := c.raw.AcknowledgeAlarm(callCtx, req)
	if err != nil {
		return nil, &GatewayError{Op: "acknowledge alarm", Err: err}
	}
	if err := EnsureProtocolSuccess("acknowledge alarm", reply.GetProtocolStatus(), nil); err != nil {
		return reply, err
	}

	return reply, nil
}

// QueryActiveAlarms streams a snapshot of all alarms currently Active or
// ActiveAcked — the gateway's ConditionRefresh equivalent. Used after reconnect
// to seed local Part 9 state, or to reconcile alarms that may have been missed
// during a transport blip.
//
// The returned stream is owned by the caller; cancel ctx to release it.
// Optional alarm-reference prefix scoping (req.AlarmFilterPrefix) limits the
// stream to a sub-tree.
func (c *Client) QueryActiveAlarms(ctx context.Context, req *QueryActiveAlarmsRequest) (QueryActiveAlarmsClient, error) {
	if req == nil {
		return nil, errors.New("mxgateway: query active alarms request is required")
	}

	stream, err := c.raw.QueryActiveAlarms(ctx, req)
	if err != nil {
		return nil, &GatewayError{Op: "query active alarms", Err: err}
	}

	return stream, nil
}

// StreamAlarms attaches to the gateway's central alarm feed. The stream opens
// with one AlarmFeedMessage per currently-active alarm (the ConditionRefresh
// snapshot), then a single snapshot-complete sentinel, then a transition for
// every subsequent raise / acknowledge / clear. It is served by the gateway's
// always-on alarm monitor — no worker session is opened — so any number of
// clients may attach.
//
// The returned stream is owned by the caller; cancel ctx to release it.
// Optional alarm-reference prefix scoping (req.AlarmFilterPrefix) limits the
// stream to a sub-tree.
func (c *Client) StreamAlarms(ctx context.Context, req *StreamAlarmsRequest) (StreamAlarmsClient, error) {
	if req == nil {
		return nil, errors.New("mxgateway: stream alarms request is required")
	}

	stream, err := c.raw.StreamAlarms(ctx, req)
	if err != nil {
		return nil, &GatewayError{Op: "stream alarms", Err: err}
	}

	return stream, nil
}
