"use strict";
const EXPORTED_SYMBOLS = ["counters"];
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
const counters = {
init: function yCounters_init(api) {
if (! this._initialized)
{
this._initialized = true;
this._api = api;
Cu.import(api.Package.resolvePath("/native/fx/modules/yauth.jsm"),this);
Cu.import(api.Package.resolvePath("/native/fx/modules/utils.jsm"),this);
this.yauth.init(api);
this.yauth.addListener("yauth-state-changed",this);
this._watchUpdIntervalPref();
}

}
,
requireService: function yCounters_requireService(serviceID, dataListener) {
var listeners = this._serviceListeners[serviceID] || (this._serviceListeners[serviceID] = []);
if (listeners.indexOf(dataListener) >= 0)
return;
listeners.push(dataListener);
if (this.yauth.authorized)
{
if (! this._reqTimer)
this._schedule();
}

}
,
requireServiceByName: function yCounters_requireService(strServiceName, dataListener) {
if (this._YA_USER_SERVICES[strServiceName])
{
this.requireService(this._YA_USER_SERVICES[strServiceName].id,dataListener);
return true;
}

return false;
}
,
ignoreService: function yCounters_ignoreService(serviceID, dataListener) {
var listeners = this._serviceListeners[serviceID];
if (! listeners)
return;
var listenerIdx = listeners.indexOf(dataListener);
if (listenerIdx < 0)
return;
listeners.splice(listenerIdx,1);
if (listeners.length < 1)
delete this._serviceListeners[serviceID];
if (! this._hasListeners)
this._stopRequests();
}
,
listenResponses: function yCounters_watchResponses(listener) {
if (this._respListeners.indexOf(listener) >= 0)
return;
this._respListeners.push(listener);
}
,
ignoreResponses: function yCounters_ignoreResponses(listener) {
var listenerIdx = this._respListeners.indexOf(listener);
if (listenerIdx >= 0)
this._respListeners.splice(listenerIdx,1);
}
,
haveDataForService: function yCounters_haveDataForService(aServiceId) {
return this._lastResponseServices && this._lastResponseServices.indexOf(String(aServiceId)) != - 1;
}
,
haveDataForServices: function yCounters_haveDataForService(aServicesList) {
for each(let serviceId in aServicesList) {
let result = this.haveDataForService(serviceId);
if (! result)
{
return false;
}

}

return true;
}
,
haveDataForServicesByName: function yCounters_haveDataForService(svcNameList) {
var srvList = [];
for each(let srvName in svcNameList) {
if (this._YA_USER_SERVICES[srvName])
{
srvList.push(this._YA_USER_SERVICES[srvName].id);
}

}

return this.haveDataForServices(srvList);
}
,
getLastResponse: function yCounters_getLastResponse() {
return [this._lastResponseFlags, this._lastResponseDoc];
}
,
_forcedUpdateTimer: false,
_bufferedCallbacks: [],
forceUpdate: function yCounters_forceUpdate(srvID, callback) {
if (callback)
{
this._bufferedCallbacks.push({
serviceName: srvID,
fn: callback});
}

if (this._forcedUpdateTimer)
return;
this._forcedUpdateTimer = true;
var logger = this._api.logger;
var finalWrapper = function (bufferedCallbacks) {
bufferedCallbacks.forEach(function (fn) {
try {
fn();
}
catch (e) {
logger.error(e);
logger.debug(e.stack);
}

}
);
}
;
var me = this;
var event = {
notify: function yCounters_forceUpdate_notify() {
var srvIDs = [];
var callbacks = [];
me._bufferedCallbacks.forEach(function (bufferedCallback) {
srvIDs.push(bufferedCallback.serviceName);
callbacks.push(bufferedCallback.fn);
}
);
me._sendRequest(srvIDs.length ? srvIDs : null,finalWrapper(callbacks));
me._forcedUpdateTimer = false;
me._bufferedCallbacks.length = 0;
}
};
var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.initWithCallback(event,100,Ci.nsITimer.TYPE_ONE_SHOT);
}
,
notify: function yCounters_notify(timer) {
this._sendRequest();
}
,
observe: function yCounters_observe(subject, topic, data) {
if (subject == this.yauth && topic == this.yauth.EVENTS.AUTH_STATE_CHANGED)
this._onAuthStateChange(data.hasAuth);
}
,
_initialized: false,
_api: null,
_minsUpdateInterval: 5,
_UPD_INT_PREFNAME: "countersUpdateInterval",
get _COUNTERS_EXPORT_URL() {
var exportURL = this._api.Localization.createStringBundle("/urls/common.properties").get("exportURLWithAuthCookies");
delete this._COUNTERS_EXPORT_URL;
return this._COUNTERS_EXPORT_URL = exportURL + "for/counters.xml";
}
,
_serviceListeners: {
},
_respListeners: [],
_reqTimer: null,
_lastResponseDoc: null,
_lastResponseServices: null,
_lastResponseFlags: null,
_YA_USER_SERVICES: {
mail: {
id: 43},
lenta: {
id: 44},
money: {
id: 45},
fotki: {
id: 46},
yaru: {
id: 47},
moikrug: {
id: 48}},
_onAuthStateChange: function yCounters__onAuthStateChange(authorized) {
if (authorized)
{
this.forceUpdate();
if (! this._reqTimer)
this._schedule();
}
 else
{
this._clear();
this._stopRequests();
}

}
,
_clear: function yCounters__clear() {
this._lastResponseDoc = this._lastResponseFlags = this._lastResponseServices = null;
this._notifyListeners(undefined,null,null);
}
,
get _updateInterval() {
return this._minsUpdateInterval * 60 * 1000;
}
,
_watchUpdIntervalPref: function yCounters__watchUpdIntervalPref() {
var updIntPrefName = this._api.Settings.getPackageBranchPath() + this._UPD_INT_PREFNAME;
var prefsModule = this._api.Settings.PrefsModule;
this._minsUpdateInterval = parseInt(prefsModule.get(updIntPrefName,5),10) || 0;
prefsModule.observe(updIntPrefName,this._onUpdIntervalChange,this);
}
,
_ignoreUpdIntervalPref: function yCounters__ignoreUpdIntervalPref() {
var updIntPrefName = this._api.Settings.getPackageBranchPath() + this._UPD_INT_PREFNAME;
this._api.Settings.PrefsModule.ignore(updIntPrefName,this._onUpdIntervalChange,this);
}
,
_onUpdIntervalChange: function yCounters__onUpdIntervalChange(newValue) {
this._minsUpdateInterval = parseInt(newValue,10) || 0;
if (this._hasListeners)
this._schedule();
}
,
get _hasListeners() {
for each(let [id, list] in Iterator(this._serviceListeners)) {
if (list && list.length)
return true;
}

return false;
}
,
_schedule: function yCounters__schedule() {
if (this._reqTimer)
{
this._reqTimer.cancel();
}
 else
{
this._reqTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
}

if (this._minsUpdateInterval > 0)
{
this._reqTimer.initWithCallback(this,this._updateInterval,this._reqTimer.TYPE_REPEATING_SLACK);
}

}
,
_stopRequests: function yCounters__stopRequests() {
if (this._reqTimer)
{
this._reqTimer.cancel();
this._reqTimer = null;
}

}
,
_sendRequest: function yCounters__sendRequest(srvIDs, callback) {
var [reqURL, reqHandler, svcList] = this._createRequestHandler(srvIDs);
if (! reqURL)
return;
var finalWrapper = function () {
reqHandler.apply(this,arguments);
if (callback)
{
callback();
}

}
;
var request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
request.mozBackgroundRequest = true;
request.open("GET",reqURL,true);
var target = request.QueryInterface(Ci.nsIDOMEventTarget);
target.addEventListener("load",finalWrapper,false);
target.addEventListener("error",finalWrapper,false);
request.send(null);
}
,
_handleReqEvent: function yCounters__handleReqEvent(event, svcList) {
var request = event.target;
var flags = Object.create(null);
if (event.type == "error" || request.status != 200)
flags.requestError = 1;
var responseDoc = request.responseXML;
if (responseDoc)
{
let rootEl = responseDoc.documentElement;
if (rootEl.hasAttribute("error"))
flags.exportError = 1; else
if (! rootEl.childNodes.length)
flags.noAuth = 1;
}
 else
{
flags.xmlError = 1;
}

if (this._emptyObject(flags))
flags.ok = 1;
this._lastResponseServices = svcList;
this._lastResponseDoc = responseDoc;
this._lastResponseFlags = flags;
if (flags.noAuth)
{
this._stopRequests();
}

this._notifyListeners(svcList,flags,responseDoc);
}
,
_notifyListeners: function yCounters__notifyListeners(svcList, flags, responseDoc) {
for each(let dataListener in this._respListeners) {
this._tryNotifyListener(dataListener,flags,responseDoc);
}

svcList = svcList || [svcID for (svcID in this._serviceListeners)];
for each(let serviceID in svcList) {
let listeners = this._serviceListeners[serviceID];
if (! listeners)
continue;
for each(let dataListener in listeners) {
this._tryNotifyListener(dataListener,flags,responseDoc);
}

}

}
,
_tryNotifyListener: function yCounters__tryNotifyListener(dataListener, flags, responseDoc) {
try {
dataListener.onCountersChange(flags,responseDoc);
}
catch (e) {
if (this._api)
{
this._api.logger.error(e);
this._api.logger.debug(e.stack);
}
 else
Cu.reportError(e);
}

}
,
_createRequestHandler: function yCounters__createRequestHandler(srvIDs) {
var paramList = srvIDs ? ["services=" + encodeURIComponent(svcID) for each (svcID in srvIDs)] : ["services=" + encodeURIComponent(svcID) for (svcID in this._serviceListeners)];
if (! paramList.length)
return [];
var reqURL = this._COUNTERS_EXPORT_URL + "?" + paramList.join("&");
var svcList = srvIDs ? srvIDs : [svcID for (svcID in this._serviceListeners)];
var reqHandler = (function yCounters__reqHandler(event) {
this._handleReqEvent(event,svcList);
}
).bind(this);
return [reqURL, reqHandler, svcList];
}
,
_emptyObject: function yCounters__emptyObject(object) {
for(let x in object) return false;
return true;
}
};
