"use strict";
var EXPORTED_SYMBOLS = ["module"];
var module = function (container) {
var log = function (message) {
container.api.logger.trace("[Mailman] " + message);
}
;
const ERROR_MESSAGE = {
MAILMAN_SEND_INVALID_ARGUMENTS_PROVIDED: "\"send()\" method's argument must be a string or an object.",
MAILMAN_SEND_INVALID_SUBJECT: "\"subject\" param of \"send()\" method must non-empty string.",
SUBSCRIBER_MUST_BE_AN_OBJECT: "Subscriber must be not-null object.",
SUBSCRIBER_MUST_HAVE_RECEIVE_METHOD: "Subscriber must implement \"receive\" method.",
SUBJECT_INVALID_TYPE: "Subject must be a string or strings array."};
var Mailman = function () {
this._subscribersBySubject = {
};
}
;
Mailman.prototype = {
constructor: Mailman,
init: function () {

}
,
finalize: function () {
this.removeAllSubscribers();
}
,
addSubscriber: function ({subscriber: subscriber, subject: subject, group: group}) {
if ("object" === typeof subject && "function" === typeof subject.pop)
{
subject.forEach(function (subject) {
this.addSubscriber({
subscriber: subscriber,
subject: subject,
group: group});
}
,this);
return;
}

if ("string" !== typeof subject)
{
throw new TypeError(ERROR_MESSAGE.SUBJECT_INVALID_TYPE);
}

var subjectSubscribers = this._subscribersBySubject[subject];
if ("undefined" == typeof subjectSubscribers)
{
subjectSubscribers = this._subscribersBySubject[subject] = [];
}

if (- 1 != subjectSubscribers.indexOf(subscriber))
{
return;
}

if ("undefined" == typeof subscriber.__mailman)
{
subscriber.__mailman = {
};
}

if ("undefined" != typeof group)
{
subscriber.__mailman.group = group;
}

subjectSubscribers.push(subscriber);
}
,
removeSubscriber: function ({subscriber: subscriber, subject: subject}) {
var subjectSubscribers = this._subscribersBySubject[subject];
if ("undefined" == typeof subjectSubscribers)
{
return;
}

var indexOfSubscriber = subjectSubscribers.indexOf(subscriber);
if (- 1 != indexOfSubscriber)
{
subjectSubscribers.splice(indexOfSubscriber,1);
}

}
,
removeSubscribersGroup: function (groupName) {
if ("undefined" == typeof groupName)
{
return;
}

for(let subject in this._subscribersBySubject) {
let subjectSubscribers = this._subscribersBySubject[subject];
for (let subscriberIndex = subjectSubscribers.length;subscriberIndex--;) {
let subscriber = subjectSubscribers[subscriberIndex];
if (groupName === subscriber.__mailman.group)
{
this.removeSubscriber({
subject: subject,
subscriber: subscriber});
}

}

}

}
,
removeAllSubscribers: function () {
this._subscribersBySubject = {
};
}
,
send: function (params) {
var subject, body;
if ("string" == typeof params)
{
subject = params;
body = null;
}
 else
if ("object" == typeof params && null !== params)
{
subject = params.subject || "";
body = "undefined" != typeof params.body ? params.body : null;
}
 else
{
throw new TypeError(ERROR_MESSAGE.MAILMAN_SEND_INVALID_ARGUMENTS_PROVIDED);
}

if (subject === "")
{
throw new TypeError(ERROR_MESSAGE.MAILMAN_SEND_INVALID_SUBJECT);
}

var data = null !== body ? this._encode(body) : null;
data = this._decode(data);
var subjectSubscribers = this._subscribersBySubject[subject];
if ("undefined" == typeof subjectSubscribers)
{
return;
}

for (let subscriberIndex = subjectSubscribers.length;subscriberIndex--;) {
let subscriber = subjectSubscribers[subscriberIndex];
if ("object" != typeof subscriber || null === subscriber)
{
throw new TypeError(ERROR_MESSAGE.SUBSCRIBER_MUST_BE_AN_OBJECT);
}

if ("function" != typeof subscriber.receive)
{
throw new TypeError(ERROR_MESSAGE.SUBSCRIBER_MUST_HAVE_RECEIVE_METHOD);
}

subscriber.receive({
subject: subject,
body: data});
}

}
,
_encode: function (data) {
if ("string" == typeof data)
{
return data;
}

return JSON.stringify(data);
}
,
_decode: function (data) {
try {
return JSON.parse(data);
}
catch (e) {
log("Error occurred while decoding data: \"" + data + "\".\n Raw data will be used.");
}

return data;
}
};
return new Mailman();
}
;
if ("undefined" !== typeof exports)
{
exports.module = module;
}

