"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AlertTemplatesData = exports.AlertTemplate = void 0;
const AsyncLock = require('async-lock');
const ts_generic_collections_linq_1 = require("ts-generic-collections-linq");
/**
 * @class
 * @name AlertTemplate
 * @public
 * @description
 *      This class represents a filter used when an alert is created to notify only some devices. <br>
 */
class AlertTemplate {
    constructor(id, name, companyId, event, description, mimeType = "text/plain", senderName, headline, instruction, contact, type = "cap", status = "Actual", scope = "Public", category = "Safety", urgency = "Immediate", severity = "Severe", certainty = "Observed") {
        /*
        let that = this;
        that.type = "cap";
        that.status = "Actual";
        that.scope = "Public";
        that.category = "Safety";
        that.urgency = "Immediate";
        that.severity = "Severe";
        that.certainty = "Observed";
        // */
        /**
         * @public
         * @readonly
         * @property {string} id The Template Id
         * @instance
         */
        this.id = id;
        /**
         * @public
         * @readonly
         * @property {string} name The Human readable string identifying this template
         * @instance
         */
        this.name = name;
        /**
         * @public
         * @readonly
         * @property {string} companyId The unique identifier of the company that own this template.  default value user logged in company Id
         * @instance
         */
        this.companyId = companyId;
        /**
         * @public
         * @readonly
         * @property {string} event The String denoting the type of the subject event of the alert message (max 255 characters)
         * @instance
         */
        this.event = event;
        /**
         * @public
         * @readonly
         * @property {string} description The String describing the subject event of the alert message (max 8192 characters)
         * @instance
         */
        this.description = description;
        /**
         * @public
         * @readonly
         * @property {string} mimeType The Mime Type of description's content (max 255 characters) - Default value: text/plain
         * @instance
         */
        this.mimeType = mimeType;
        /**
         * @public
         * @readonly
         * @property {string} senderName The String naming the originator of the alert message (max 255 characters)
         * @instance
         */
        this.senderName = senderName;
        /**
         * @public
         * @readonly
         * @property {string} headline The headline of the alert message (max 255 characters) used for short message devices that may only presents this field (mobile device push)
         * @instance
         */
        this.headline = headline;
        /**
         * @public
         * @readonly
         * @property {string} instruction The text representing the recommended action (max 4096 characters)
         * @instance
         */
        this.instruction = instruction;
        /**
         * @public
         * @readonly
         * @property {string} contact The contact for follow-up or confirmation of the alert message (optional)
         * @instance
         */
        this.contact = contact;
        /**
         * @public
         * @readonly
         * @property {string} type The templates type only 'cap' is allowed
         * @instance
         */
        this.type = type;
        /**
         * @public
         * @readonly
         * @property {string} status The templates status ( 'Actual', 'Exercise', 'System', 'Test','Draft') - default: Actual
         * @instance
         */
        this.status = status;
        /**
         * @public
         * @readonly
         * @property {string} scope The templates scope ( 'Public', 'Restricted', 'Alert') - Default value: Public
         * @instance
         */
        this.scope = scope;
        /**
         * @public
         * @readonly
         * @property {string} category The template category ('Geo', 'Met', 'Safety', 'Security', 'Rescue', 'Fire', 'Health', 'Env', 'Transport', 'Infra', 'CBRNE', 'Other') - Default value: Safety
         * @instance
         */
        this.category = category;
        /**
         * @public
         * @readonly
         * @property {string} urgency The template urgency ('Immediate', 'Expected', 'Future', 'Past', 'Unknown') - Default value: Immediate
         * @instance
         */
        this.urgency = urgency;
        /**
         * @public
         * @readonly
         * @property {string} severity The template severity ('Extreme', 'Severe', 'Moderate', 'Minor', 'Unknown') - Default value: Severe
         * @instance
         */
        this.severity = severity;
        /**
         * @public
         * @readonly
         * @property {string} certainty The template certainty ('Observed', 'Likely', 'Possible', 'Unlikely', 'Unknown') - Default value: Observed
         * @instance
         */
        this.certainty = certainty;
    }
}
exports.AlertTemplate = AlertTemplate;
/**
 * @class
 * @name AlertTemplatesData
 * @description
 *      This class represents a Structure used when retrieving severals AlertTemplate from server. <br>
 */
class AlertTemplatesData {
    constructor(limit = 0) {
        //public data: List<AlertTemplate>
        this.alertTemplates = new ts_generic_collections_linq_1.Dictionary();
        this.lockKey = "LOCK_AlertTemplate";
        this.lockEngine = new AsyncLock({ timeout: 5000, maxPending: 1000 });
        /**
         * @public
         * @readonly
         * @property {List<string>} data The List of AlertTemplate found
         * @instance
         */
        // this.data = new List<AlertTemplate>();
        /**
         * @public
         * @readonly
         * @property {number} total The Total number of items available
         * @instance
         */
        this.total = 0;
        /**
         * @public
         * @readonly
         * @property {number} limit The Number of items asked
         * @instance
         */
        this.limit = limit;
        /**
         * @public
         * @readonly
         * @property {number} offset The Offset used
         * @instance
         */
        this.offset = 0;
    }
    //region Lock
    lock(fn) {
        let that = this;
        let opts = undefined;
        return that.lockEngine.acquire(that.lockKey, async function () {
            // that._logger.log("debug", LOG_ID + "(lock) lock the ", that.lockKey);
            //that._logger.log("internal", LOG_ID + "(lock) lock the ", that.lockKey);
            return await fn(); // async work
        }, opts).then((result) => {
            // that._logger.log("debug", LOG_ID + "(lock) release the ", that.lockKey);
            //that._logger.log("internal", LOG_ID + "(lock) release the ", that.lockKey, ", result : ", result);
            return result;
        });
    }
    //endregion
    // region Add/get/first/last/remove AlertTemplate
    addAlertTemplate(alertTemplate) {
        let that = this;
        return new Promise((resolve, reject) => {
            that.lock(() => {
                // Treatment in the lock
                if ((!that.alertTemplates.containsKey(alertTemplate.id))) {
                    that.total++;
                    that.alertTemplates.add(alertTemplate.id, alertTemplate);
                    //needToAsk = true;
                    return alertTemplate;
                }
                return;
            }).then((result) => {
                return resolve(result);
            }).catch((result) => {
                resolve(undefined);
            });
        });
    }
    async removeBubbleToJoin(alertTemplate) {
        let that = this;
        return new Promise((resolve, reject) => {
            that.lock(() => {
                // Treatment in the lock
                if ((that.alertTemplates.containsKey(alertTemplate.id))) {
                    that.alertTemplates.remove((item) => {
                        return alertTemplate.id === item.key;
                    });
                    //needToAsk = true;
                }
            }).then((result) => {
                resolve(result);
            }).catch((result) => {
                resolve(undefined);
            });
        });
    }
    async getAlertTemplate() {
        let that = this;
        return new Promise((resolve, reject) => {
            that.lock(() => {
                // Treatment in the lock
                let item = that.alertTemplates.elementAt(0);
                if (!item)
                    return;
                let id = item.key;
                let alertTemplate = item.value;
                that.alertTemplates.remove((item) => {
                    return id === item.key;
                });
                return alertTemplate;
            }).then((result) => {
                resolve(result);
            }).catch((result) => {
                resolve(undefined);
            });
        });
    }
    first() {
        let that = this;
        return new Promise((resolve, reject) => {
            that.lock(() => {
                // Treatment in the lock
                let item = that.alertTemplates.elementAt(0);
                return item.value;
            }).then((result) => {
                return resolve(result);
            }).catch((result) => {
                resolve(undefined);
            });
        });
    }
    last() {
        let that = this;
        return new Promise((resolve, reject) => {
            that.lock(() => {
                // Treatment in the lock
                let item = that.alertTemplates.elementAt(that.total);
                return item.value;
            }).then((result) => {
                //that._logger.log("internal", LOG_ID + "(addBubbleToJoin) Succeed - Jid : ", result);
                return resolve(result);
            }).catch((result) => {
                //that._logger.log("internal", LOG_ID + "(addBubbleToJoin) Failed - Jid : ", result);
                resolve(undefined);
            });
        });
    }
}
exports.AlertTemplatesData = AlertTemplatesData;
module.exports = { AlertTemplate, AlertTemplatesData };
//# sourceMappingURL=AlertTemplate.js.map