'use strict';

Object.defineProperty(exports, '__esModule', {
  value: true
});

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

var _swarmLibNodeServer = require('swarm/lib/NodeServer');

var _swarmLibNodeServer2 = _interopRequireDefault(_swarmLibNodeServer);

var _swarmfactory = require('./swarmfactory');

var _swarmfactory2 = _interopRequireDefault(_swarmfactory);

var _swarmLibSpec = require('swarm/lib/Spec');

var _swarmLibSpec2 = _interopRequireDefault(_swarmLibSpec);

var _redis = require('redis');

var _redis2 = _interopRequireDefault(_redis);

var _vendorSwarmRedisStorage = require('../vendor/swarm/RedisStorage');

var _vendorSwarmRedisStorage2 = _interopRequireDefault(_vendorSwarmRedisStorage);

var SwarmServer = (function () {
  function SwarmServer(redisConfig) {
    var _this = this;

    _classCallCheck(this, SwarmServer);

    var Swarm = (0, _swarmfactory2['default'])(_swarmLibNodeServer2['default']);
    this.Swarm = Swarm;

    //let storage = new Swarm.FileStorage('.swarm')
    var storage = new _vendorSwarmRedisStorage2['default']({
      redis: _redis2['default'],
      redisConnectParams: redisConfig,
      debug: false
    });
    storage.open();

    Swarm.host = new Swarm.Host('swarm~nodejs', 0, storage);
    Swarm.env.localhost = Swarm.host;

    setInterval(function () {
      _this.cleanCursorSets();
    }, 5000);
  }

  _createClass(SwarmServer, [{
    key: 'cleanCursorSet',
    value: function cleanCursorSet(cursorSet) {
      var online = {};
      var Swarm = this.Swarm;
      for (var src in Swarm.host.sources) {
        if (!Swarm.host.sources.hasOwnProperty(src)) continue;
        var m = src.match(/([A-Za-z0-9_\~]+)(\~[A-Za-z0-9_\~]+)/);
        if (!m) {
          console.error('Unknown Swarm source', src);
          continue;
        }
        online[m[1]] = true;
      }

      if (!cursorSet._version) {
        return;
      }

      var cursorSetMoribund = {};
      var cursors = cursorSet.list();
      var _iteratorNormalCompletion = true;
      var _didIteratorError = false;
      var _iteratorError = undefined;

      try {
        for (var _iterator = cursors[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
          var s = _step.value;

          var spec = s.spec();
          if (spec.type() !== 'Cursor') {
            continue;
          }
          var id = spec.id();
          cursorSetMoribund[id] = s.ms;
        }
        //console.log('cursorSet:', cursorSet._id, 'cursors:', cursorSetMoribund)
        // cursors live for 10 minutes after last use and then disappear (recreated by client if user resumes editing)
      } catch (err) {
        _didIteratorError = true;
        _iteratorError = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion && _iterator['return']) {
            _iterator['return']();
          }
        } finally {
          if (_didIteratorError) {
            throw _iteratorError;
          }
        }
      }

      var ancient = Date.now() - 60 * 60 * 1000;
      for (var id in cursorSetMoribund) {
        if (!cursorSetMoribund.hasOwnProperty(id)) continue;
        var ts = cursorSetMoribund[id];
        if (ts < ancient) {
          cursorSet.removeObject('/Cursor#' + id);
          delete cursorSetMoribund[id];
        }
      }
    }
  }, {
    key: 'cleanCursorSets',
    value: function cleanCursorSets() {
      var _this2 = this;

      var Swarm = this.Swarm;
      Object.keys(Swarm.host.objects).map(function (s) {
        return new _swarmLibSpec2['default'](s);
      }).filter(function (s) {
        return s.type() === 'CursorSet';
      }).forEach(function (s) {
        _this2.cleanCursorSet(Swarm.host.get(s));
      });
    }
  }]);

  return SwarmServer;
})();

exports['default'] = SwarmServer;
module.exports = exports['default'];