"use strict";
var EXPORTED_SYMBOLS = ["module"];
var module = function (container) {
var log = function (message) {
container.api.logger.trace("[Cache] " + message);
}
;
function Cache(fileName) {
this._fileName = fileName;
this._data = {
__proto__: null};
this._loaded = false;
this.__file = null;
}

Cache.IDLE_TIMEOUT = 60;
Cache.prototype = {
constructor: Cache,
get _file() {
if (null === this.__file)
{
this.__file = container.api.Files.getWidgetStorage(true);
this.__file.append(this._fileName);
}

return this.__file;
}
,
_load: function () {
log("Trying to load data from " + this._fileName);
var file = this._file;
try {
let text = container.api.Files.readTextFile(file);
this._data = JSON.parse(text);
}
catch (e) {
log("Error occurred while reading from " + this._fileName);
}

this._loaded = true;
}
,
_unload: function () {
if (! this._loaded)
return;
log("Unload.");
this._data = {
__proto__: null};
this._loaded = false;
}
,
_save: function () {
log("Write data to " + this._fileName);
var file = this._file;
var string = JSON.stringify(this._data);
container.api.Files.writeTextFile(file,string);
}
,
_getTimestamp: function () {
return (new Date()).getTime();
}
,
_unloadTimer: null,
_logActivity: function () {
if (null === this._unloadTimer)
{
this._unloadTimer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
}
 else
{
this._unloadTimer.cancel();
}

var cache = this;
this._unloadTimer.init({
observe: function () {
cache._unload();
}
},Cache.IDLE_TIMEOUT * 1000,Components.interfaces.nsITimer.TYPE_ONE_SHOT);
}
,
get: function (key) {
this._logActivity();
if (! this._loaded)
{
this._load();
}

var entry = this._data[key] || null;
if (null === entry)
{
return null;
}

var value = entry.value;
if ("undefined" != typeof entry.expirationDate)
{
let isExpired = this._getTimestamp() >= entry.expirationDate;
if (isExpired)
{
value = null;
}

}

return value;
}
,
put: function (key, value, expiresIn) {
this._logActivity();
if ("string" !== typeof value)
{
throw TypeError("Only strings can be saved in cache.");
}

if (! this._loaded)
{
this._load();
}

log("Save " + key + " => " + value);
this._data[key] = {
value: value};
if ("number" == typeof expiresIn)
{
this._data[key].expirationDate = this._getTimestamp() + expiresIn;
}

this._save();
}
,
remove: function (key) {
this._logActivity();
var value = this.get(key);
if (null === value)
{
return;
}

delete this._data[key];
this._save();
}
,
clear: function () {
this._logActivity();
log("Clear.");
this._data = {
};
this._save();
}
};
return Cache;
}
;
if ("undefined" !== typeof exports)
{
exports.module = module;
}

