'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 _swarm = require('swarm');

var _swarm2 = _interopRequireDefault(_swarm);

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

var _swarmfactory2 = _interopRequireDefault(_swarmfactory);

var SwarmClient = (function () {
  function SwarmClient(localUser) {
    var _this = this;

    _classCallCheck(this, SwarmClient);

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

    this.id = localUser;

    // server host uri (/websocket is appended because https://github.com/websockets/ws/issues/131)
    this.wsServerUri = 'ws://' + window.location.host + '/websocket';

    var hash = window.location.hash || '#0';

    // create Host
    this.host = Swarm.env.localhost = new Swarm.Host(this.id + hash.replace('#', '~'));

    // connect to server
    this.pipe = this.host.connect(this.wsServerUri, { delay: -1 });

    this.reonHooks = [];
    this.unloadHooks = [];

    //catch online/offline status changes
    this.host.on('reon', function (spec, val) {
      // eslint-disable-line no-unused-vars
      document.body.setAttribute('connected', _this.host.isUplinked());
      for (var i = 0; i < _this.reonHooks.length; i++) {
        try {
          _this.reonHooks[i]();
        } catch (e) {
          console.warn('Swarm reon hook failed.', e);
        }
      }
    });
    this.host.on('reoff', function (spec, val) {
      // eslint-disable-line no-unused-vars
      document.body.setAttribute('connected', _this.host.isUplinked());
    });
    this.host.on('off', function (spec, val) {
      // eslint-disable-line no-unused-vars
      document.body.setAttribute('connected', _this.host.isUplinked());
    });

    var unloaded = false;
    var unload = function unload() {
      if (unloaded) {
        return;
      }
      unloaded = true;
      // bug, Swarm.js does not close the Websocket because Pipe.close() expects stream.close() to exist, get a ref and do it manually
      var ws = _this.pipe && _this.pipe.stream && _this.pipe.stream.ws ? _this.pipe.stream.ws : null;
      for (var i = 0; i < _this.unloadHooks.length; i++) {
        try {
          _this.unloadHooks[i]();
        } catch (e) {
          console.warn('Swarm unload hook failed.', e);
        }
      }
      _this.host.close(function () {
        // bug, Swarm.js does not close the Websocket because Pipe.close() expects stream.close() to exist
        _this.pipe.close();
        if (ws) {
          ws.close();
        }
      });
    };

    // hopefully one of these events works, doesn't seem to be consistent
    window.addEventListener('beforeunload', function () {
      unload();
    });
    window.addEventListener('pagehide', function () {
      unload();
    });
    window.addEventListener('unload', function () {
      unload();
    });
  }

  _createClass(SwarmClient, [{
    key: 'addReonHook',
    value: function addReonHook(f) {
      this.reonHooks.push(f);
    }
  }, {
    key: 'addUnloadHook',
    value: function addUnloadHook(f) {
      this.unloadHooks.push(f);
    }
  }]);

  return SwarmClient;
})();

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