const EventEmitter = require('events');
const DHT = require('bittorrent-dht')
const crypto = require('crypto');
const WebTorrent = require('webtorrent')
const ChunkStore = require('memory-chunk-store')

function NoopChunkStore(chunkLength, options) {
  console.log(options);
}

function callbackImmediate(...args) {
  const callback = args.pop()
  if ('function' === typeof callback) {
    callback()
  }
}

['get', 'put', 'close', 'destroy'].forEach((method) => {
  NoopChunkStore.prototype[method] = callbackImmediate
})

class Sniffer extends EventEmitter {

  constructor(options) {
    super()

    this.options = options || {};

    this.bt = new WebTorrent({maxConns: 1})

    this.bt.on('error', (error) => {
      console.error(error.message);
    })

    const locks = new Set

    const dht = new DHT({concurrency: 30});
    this.dht = dht
    dht.on('announce_peer', (infoHash, peer) => {
      if (this.bt.torrents.length >= 200) {
        //console.log('bt client is busy, drop peer');
        return
      }
      const lock = infoHash.toString('hex')
      if (locks.has(lock)) {
        return
      }
      locks.add(lock)
      this._ignore(infoHash, (drop) => {
        //console.log(this.bt.torrents.length);
        if (drop) {
          return locks.delete(lock)
        }
        //const torrent = this.bt.add(infoHash, {store})
        const torrent = this.bt.add(infoHash, { store: ChunkStore })
        torrent.addPeer(`${peer.host}:${peer.port}`)
        torrent.once('metadata', () => {
          this.bt.remove(torrent)
          torrent.done = true
          this.emit('metadata', torrent, () => locks.delete(lock))
        })
      })
    })

    const rpc = dht._rpc
    rpc.on('ping', (olders, newer) => {
      for (const older of olders) {
        rpc.nodes.remove(older.id)
      }
      //rpc.clear()
    })
    dht.on('node', (node) => this.makeNeighbor(node))
  }

  makeNeighbor(node, id) {
    const rpc = this.dht._rpc
    // prevent memleak
    if (rpc.pending.length) {
      return
    }
    const query = {
      t: crypto.randomBytes(4),
      y: 'q',
      q: 'find_node',
      a: {
        id: id || Buffer.concat([node.id.slice(0, 10), rpc.id.slice(10)]),
        target: crypto.randomBytes(20)
      }
    };
    rpc.query(node, query)
  }

  ignore(callback) {
    this._ignore = callback;
  };

  start(...args) {
    this.dht.listen(...args)

    setInterval(() => {
      const rpc = this.dht._rpc
      rpc.bootstrap.forEach((node) => this.makeNeighbor(node, rpc.id))
    }, 1000)
  };

  sniff() {
    //this.dht._bootstrap(true)
    //if (this.bt.isIdle()) {
      //this.dht.joinDHTNetwork();
      //this.dht.makeNeighbours();
    //}
  }

}

module.exports = Sniffer;

@@ -200,329 +200,8 @@
 ')%0A%0A
-function NoopChunkStore(chunkLength, options) %7B%0A  console.log(options);%0A%7D%0A%0Afunction callbackImmediate(...args) %7B%0A  const callback = args.pop()%0A  if ('function' === typeof callback) %7B%0A    callback()%0A  %7D%0A%7D%0A%0A%5B'get', 'put', 'close', 'destroy'%5D.forEach((method) =%3E %7B%0A  NoopChunkStore.prototype%5Bmethod%5D = callbackImmediate%0A%7D)%0A%0A
 clas

Remove unused class