"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("events");
const node_opcua_assert_1 = require("node-opcua-assert");
const client_alarm_1 = require("./client_alarm");
// maintain a set of alarm list for a client
class ClientAlarmList extends events_1.EventEmitter {
    constructor() {
        super();
        this._map = {};
    }
    [Symbol.iterator]() {
        let pointer = 0;
        const components = Object.values(this._map);
        return {
            next() {
                if (pointer >= components.length) {
                    return {
                        done: true,
                        value: components[pointer++]
                    };
                }
                else {
                    return {
                        done: false,
                        value: components[pointer++]
                    };
                }
            }
        };
    }
    alarms() {
        return Object.values(this._map);
    }
    update(eventField) {
        // Spec says: 
        // Clients shall check for multiple Event Notifications for a ConditionBranch to avoid
        // overwriting a new state delivered together with an older state from the Refresh
        // process.
        const { conditionId, eventType } = eventField;
        node_opcua_assert_1.assert(conditionId, "must have a valid conditionId ( verify that event is a acknodweldgeable type");
        const alarm = this.findAlarm(conditionId.value, eventType.value);
        if (!alarm) {
            const key = this.makeKey(conditionId.value, eventType.value);
            const newAlarm = new client_alarm_1.ClientAlarm(eventField);
            this._map[key] = newAlarm;
            this.emit("newAlarm", newAlarm);
            this.emit("alarmChanged", alarm);
        }
        else {
            alarm.update(eventField);
            this.emit("alarmChanged", alarm);
        }
    }
    removeAlarm(eventField) {
        const { conditionId, eventType } = eventField;
        const alarm = this.findAlarm(conditionId.value, eventType.value);
        if (alarm) {
            alarm.update(eventField);
            this._removeAlarm(alarm);
        }
    }
    get length() {
        return Object.keys(this._map).length;
    }
    purgeUnusedAlarms() {
        const alarms = this.alarms();
        for (const alarm of alarms) {
            if (!alarm.getRetain()) {
                this._removeAlarm(alarm);
            }
        }
    }
    _removeAlarm(alarm) {
        this.emit("alarmDeleted", alarm);
        this.deleteAlarm(alarm.conditionId, alarm.eventType);
    }
    makeKey(conditionId, eventType) {
        return conditionId.toString() + "|" + eventType.toString();
    }
    findAlarm(conditionId, eventType) {
        const key = this.makeKey(conditionId, eventType);
        const _c = this._map[key];
        return _c || null;
    }
    deleteAlarm(conditionId, eventType) {
        const key = this.makeKey(conditionId, eventType);
        const _c = this._map[key];
        if (_c) {
            delete this._map[key];
            return true;
        }
        return false;
    }
}
exports.ClientAlarmList = ClientAlarmList;
//# sourceMappingURL=client_alarm_list.js.map