'use strict';

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

var utils = require('./utils.js');
var chai_js = require('aegir/utils/chai.js');
var mocha = require('../utils/mocha.js');
var delay = require('delay');
var env_js = require('ipfs-utils/src/env.js');
var ipfsOptionsWebsocketsFilterAll = require('../utils/ipfs-options-websockets-filter-all.js');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var delay__default = /*#__PURE__*/_interopDefaultLegacy(delay);

function testPeers(factory, options) {
  const ipfsOptions = ipfsOptionsWebsocketsFilterAll.ipfsOptionsWebsocketsFilterAll();
  const describe = mocha.getDescribe(options);
  const it = mocha.getIt(options);
  describe('.pubsub.peers', function () {
    this.timeout(80 * 1000);
    let ipfs1;
    let ipfs2;
    let ipfs3;
    let subscribedTopics = [];
    let ipfs2Id;
    let ipfs3Id;
    before(async () => {
      ipfs1 = (await factory.spawn({ ipfsOptions })).api;
      ipfs2 = (await factory.spawn({
        type: env_js.isWebWorker ? 'js' : undefined,
        ipfsOptions
      })).api;
      ipfs3 = (await factory.spawn({
        type: env_js.isWebWorker ? 'js' : undefined,
        ipfsOptions
      })).api;
      ipfs2Id = await ipfs2.id();
      ipfs3Id = await ipfs3.id();
      const ipfs2Addr = ipfs2Id.addresses.find(ma => ma.nodeAddress().address === '127.0.0.1');
      const ipfs3Addr = ipfs3Id.addresses.find(ma => ma.nodeAddress().address === '127.0.0.1');
      if (!ipfs2Addr || !ipfs3Addr) {
        throw new Error('Could not find addrs');
      }
      await ipfs1.swarm.connect(ipfs2Addr);
      await ipfs1.swarm.connect(ipfs3Addr);
      await ipfs2.swarm.connect(ipfs3Addr);
    });
    afterEach(async () => {
      const nodes = [
        ipfs1,
        ipfs2,
        ipfs3
      ];
      for (let i = 0; i < subscribedTopics.length; i++) {
        const topic = subscribedTopics[i];
        await Promise.all(nodes.map(ipfs => ipfs.pubsub.unsubscribe(topic)));
      }
      subscribedTopics = [];
      await delay__default["default"](100);
    });
    after(() => factory.clean());
    it('should not error when not subscribed to a topic', async () => {
      const topic = utils.getTopic();
      const peers = await ipfs1.pubsub.peers(topic);
      chai_js.expect(peers).to.exist();
    });
    it('should not return extra peers', async () => {
      const sub1 = () => {
      };
      const sub2 = () => {
      };
      const sub3 = () => {
      };
      const topic = utils.getTopic();
      const topicOther = topic + 'different topic';
      subscribedTopics = [
        topic,
        topicOther
      ];
      await ipfs1.pubsub.subscribe(topic, sub1);
      await ipfs2.pubsub.subscribe(topicOther, sub2);
      await ipfs3.pubsub.subscribe(topicOther, sub3);
      const peers = await ipfs1.pubsub.peers(topic);
      chai_js.expect(peers).to.be.empty();
    });
    it('should return peers for a topic - one peer', async () => {
      const sub1 = () => {
      };
      const sub2 = () => {
      };
      const sub3 = () => {
      };
      const topic = utils.getTopic();
      subscribedTopics = [topic];
      await ipfs1.pubsub.subscribe(topic, sub1);
      await ipfs2.pubsub.subscribe(topic, sub2);
      await ipfs3.pubsub.subscribe(topic, sub3);
      await utils.waitForPeers(ipfs1, topic, [ipfs2Id.id], 30000);
    });
    it('should return peers for a topic - multiple peers', async () => {
      const sub1 = () => {
      };
      const sub2 = () => {
      };
      const sub3 = () => {
      };
      const topic = utils.getTopic();
      subscribedTopics = [topic];
      await ipfs1.pubsub.subscribe(topic, sub1);
      await ipfs2.pubsub.subscribe(topic, sub2);
      await ipfs3.pubsub.subscribe(topic, sub3);
      await utils.waitForPeers(ipfs1, topic, [
        ipfs2Id.id,
        ipfs3Id.id
      ], 30000);
    });
  });
}

exports.testPeers = testPeers;
