text: 'use strict';
  var test = require('./shared').assert;
  var co = require('co');
  var mock = require('mongodb-mock-server');
  const { ReadPreference, ObjectId } = require('../../src');
  
  var extend = function(template, fields) {
    var object = {};
    for (var name in template) {
      object[name] = template[name];
    }
  
    for (var fieldName in fields) {
      object[fieldName] = fields[name];
    }
  
    return object;
  };
  
  describe.skip('Buffering Proxy', function() {
    afterEach(() => mock.cleanup());
  
    it('successfully handle buffering store execution for primary server', {
      metadata: {
        requires: {
          generators: true,
          topology: 'single'
        }
      },
  
      test: function(done) {
        var configuration = this.configuration;
        var currentIsMasterIndex = 0;
        var electionIds = [new ObjectId(0), new ObjectId(1)];
  
        // Default message fields
        var defaultFields = Object.assign({}, mock.DEFAULT_ISMASTER, {
          setName: 'rs',
          setVersion: 1,
          electionId: electionIds[0],
          hosts: ['localhost:32000', 'localhost:32001', 'localhost:32002'],
          arbiters: ['localhost:32002']
        });
  
        // Primary server states
        var primary = [
          extend(defaultFields, {
            ismaster: true,
            secondary: false,
            me: 'localhost:32000',
            primary: 'localhost:32000',
            tags: { loc: 'ny' }
          }),
          extend(defaultFields, {
            ismaster: false,
            secondary: true,
            me: 'localhost:32000',
            primary: 'localhost:32000',
            tags: { loc: 'ny' }
          }),
          extend(defaultFields, {
            ismaster: false,
            secondary: true,
            me: 'localhost:32000',
            primary: 'localhost:32001',
            tags: { loc: 'ny' },
            electionId: electionIds[1]
          })
        ];
  
        // Primary server states
        var firstSecondary = [
          extend(defaultFields, {
            ismaster: false,
            secondary: true,
            me: 'localhost:32001',
            primary: 'localhost:32000',
            tags: { loc: 'sf' }
          }),
          extend(defaultFields, {
            ismaster: false,
            secondary: true,
            me: 'localhost:32001',
            primary: 'localhost:32000',
            tags: { loc: 'sf' }
          }),
          extend(defaultFields, {
            ismaster: true,
            secondary: false,
            me: 'localhost:32001',
            primary: 'localhost:32001',
            tags: { loc: 'ny' },
            electionId: electionIds[1]
          })
        ];
  
        // Primary server states
        var secondSecondary = [
          extend(defaultFields, {
            ismaster: false,
            secondary: true,
            me: 'localhost:32002',
            primary: 'localhost:32000',
            tags: { loc: 'sf' }
          }),
          extend(defaultFields, {
            ismaster: false,
            secondary: true,
            me: 'localhost:32002',
            primary: 'localhost:32000',
            tags: { loc: 'sf' }
          }),
          extend(defaultFields, {
            ismaster: false,
            secondary: true,
            me: 'localhost:32002',
            primary: 'localhost:32001',
            tags: { loc: 'ny' },
            electionId: electionIds[1]
          })
        ];
  
        // Die
        var die = false;
        var dieSecondary = false;
  
        // Boot the mock
        co(function*() {
          const primaryServer = yield mock.createServer(32000, 'localhost');
          const firstSecondaryServer = yield mock.createServer(32001, 'localhost');
          const secondSecondaryServer = yield mock.createServer(32002, 'localhost');
  
          primaryServer.setMessageHandler(request => {
            var doc = request.document;
  
            if (die) {
              request.connection.destroy();
            } else {
              if (doc.ismaster) {
                request.reply(primary[currentIsMasterIndex]);
              } else if (doc.insert) {
                request.reply({ ok: 1, n: 1 });
              } else if (doc.aggregate) {
                request.reply({ ok: 1, n: 1 });
              } else if (doc.endSessions) {
                request.reply({ ok: 1 });
              }
            }
          });
  
          firstSecondaryServer.setMessageHandler(request => {
            var doc = request.document;
  
            if (die || dieSecondary) {
              request.connection.destroy();
            } else {
              if (doc.ismaster) {
                request.reply(firstSecondary[currentIsMasterIndex]);
              } else if (doc.endSessions) {
                request.reply({ ok: 1 });
              }
            }
          });
  
          secondSecondaryServer.setMessageHandler(request => {
            var doc = request.document;
  
            if (die || dieSecondary) {
              request.connection.destroy();
            } else {
              if (doc.ismaster) {
                request.reply(secondSecondary[currentIsMasterIndex]);
              } else if (doc.endSessions) {
                request.reply({ ok: 1 });
              }
            }
          });
  
          const client = configuration.newClient(
            'mongodb://localhost:32000,localhost:32001,localhost:32002/test?replicaSet=rs',
            {
              socketTimeoutMS: 2000,
              haInterval: 1000
            }
          );
  
          client.connect(function(err, client) {
            test.equal(null, err);
            var db = client.db(configuration.db);
            var results = [];
  
            setTimeout(function() {
              die = true;
              dieSecondary = true;
  
              setTimeout(function() {
                db.collection('test').insertOne({ a: 1 }, function(err) {
                  test.equal(null, err);
                  results.push('insertOne');
                });
  
                db.command(
                  { count: 'test', query: {} },
                  { readPreference: new ReadPreference(ReadPreference.SECONDARY) },
                  function(err) {
                    test.equal(null, err);
                    results.push('count');
                  }
                );
  
                db.collection('test')
                  .aggregate([{ $match: {} }])
                  .toArray(function(err) {
                    test.equal(null, err);
                    results.push('aggregate');
                  });
  
                db.collection('test')
                  .find({})
                  .setReadPreference(new ReadPreference(ReadPreference.SECONDARY))
                  .toArray(function(err) {
                    test.equal(null, err);
                    results.push('find');
                  });
  
                setTimeout(function() {
                  die = false;
  
                  setTimeout(function() {
                    test.deepEqual(['insertOne', 'aggregate'].sort(), results.sort());
                    client.close(done);
                  }, 1000);
                }, 1000);
              }, 3000);
            }, 1000);
          });
        });
      }
    });
  
    it('successfully handle buffering store execution for secondary server', {
      metadata: {
        requires: {
          generators: true,
          topology: 'single'
        }
      },
  
      test: function(done) {
        var configuration = this.configuration;
        var currentIsMasterIndex = 0;
        var electionIds = [new ObjectId(0), new ObjectId(1)];
  
        // Default message fields
        var defaultFields = Object.assign({}, mock.DEFAULT_ISMASTER, {
          setName: 'rs',
          setVersion: 1,
          electionId: electionIds[0],
          hosts: ['localhost:32000', 'localhost:32001', 'localhost:32002'],
          arbiters: ['localhost:32002']
        });
  
        // Primary server states
        var primary = [
          extend(defaultFields, {
            ismaster: true,
            secondary: false,
            me: 'localhost:32000',
            primary: 'localhost:32000',
            tags: { loc: 'ny' }
          }),
          extend(defaultFields, {
            ismaster: false,
            secondary: true,
            me: 'localhost:32000',
            primary: 'localhost:32000',
            tags: { loc: 'ny' }
          }),
          extend(defaultFields, {
            ismaster: false,
            secondary: true,
            me: 'localhost:32000',
            primary: 'localhost:32001',
            tags: { loc: 'ny' },
            electionId: electionIds[1]
          })
        ];
  
        // Primary server states
        var firstSecondary = [
          extend(defaultFields, {
            ismaster: false,
            secondary: true,
            me: 'localhost:32001',
            primary: 'localhost:32000',
            tags: { loc: 'sf' }
          }),
          extend(defaultFields, {
            ismaster: false,
            secondary: true,
            me: 'localhost:32001',
            primary: 'localhost:32000',
            tags: { loc: 'sf' }
          }),
          extend(defaultFields, {
            ismaster: true,
            secondary: false,
            me: 'localhost:32001',
            primary: 'localhost:32001',
            tags: { loc: 'ny' },
            electionId: electionIds[1]
          })
        ];
  
        // Primary server states
        var secondSecondary = [
          extend(defaultFields, {
            ismaster: false,
            secondary: true,
            me: 'localhost:32002',
            primary: 'localhost:32000',
            tags: { loc: 'sf' }
          }),
          extend(defaultFields, {
            ismaster: false,
            secondary: true,
            me: 'localhost:32002',
            primary: 'localhost:32000',
            tags: { loc: 'sf' }
          }),
          extend(defaultFields, {
            ismaster: false,
            secondary: true,
            me: 'localhost:32002',
            primary: 'localhost:32001',
            tags: { loc: 'ny' },
            electionId: electionIds[1]
          })
        ];
  
        // Die
        var die = false;
        var diePrimary = false;
  
        // Boot the mock
        co(function*() {
          const primaryServer = yield mock.createServer(32000, 'localhost');
          const firstSecondaryServer = yield mock.createServer(32001, 'localhost');
          const secondSecondaryServer = yield mock.createServer(32002, 'localhost');
  
          primaryServer.setMessageHandler(request => {
            var doc = request.document;
  
            if (die || diePrimary) {
              request.connection.destroy();
            } else {
              if (doc.ismaster) {
                request.reply(primary[currentIsMasterIndex]);
              } else if (doc.endSessions) {
                request.reply({ ok: 1 });
              }
            }
          });
  
          firstSecondaryServer.setMessageHandler(request => {
            var doc = request.document;
  
            if (die) {
              request.connection.destroy();
            } else {
              if (doc.ismaster) {
                request.reply(firstSecondary[currentIsMasterIndex]);
              } else if (doc.count) {
                request.reply({ ok: 1, n: 10 });
              } else if (doc.find) {
                request.reply({ ok: 1, n: 10 });
              } else if (doc.endSessions) {
                request.reply({ ok: 1 });
              }
            }
          });
  
          secondSecondaryServer.setMessageHandler(request => {
            var doc = request.document;
  
            if (die) {
              request.connection.destroy();
            } else {
              if (doc.ismaster) {
                request.reply(secondSecondary[currentIsMasterIndex]);
              } else if (doc.count) {
                request.reply({ ok: 1, n: 10 });
              } else if (doc.find) {
                request.reply({ ok: 1, n: 10 });
              } else if (doc.endSessions) {
                request.reply({ ok: 1 });
              }
            }
          });
  
          const client = configuration.newClient(
            'mongodb://localhost:32000,localhost:32001,localhost:32002/test?replicaSet=rs',
            {
              socketTimeoutMS: 2000,
              haInterval: 1000
            }
          );
  
          client.connect(function(err, client) {
            test.equal(null, err);
            var db = client.db(configuration.db);
  
            setTimeout(function() {
              die = true;
              diePrimary = true;
  
              setTimeout(function() {
                var results = [];
  
                db.collection('test').insertOne({ a: 1 }, function(err) {
                  test.equal(null, err);
                  results.push('insertOne');
                });
  
                db.command(
                  { count: 'test', query: {} },
                  { readPreference: new ReadPreference(ReadPreference.SECONDARY) },
                  function(err) {
                    test.equal(null, err);
                    results.push('count');
                  }
                );
  
                db.collection('test')
                  .aggregate([{ $match: {} }])
                  .toArray(function(err) {
                    test.equal(null, err);
                    results.push('aggregate');
                  });
  
                db.collection('test')
                  .find({})
                  .setReadPreference(new ReadPreference(ReadPreference.SECONDARY))
                  .toArray(function(err) {
                    test.equal(null, err);
                    results.push('find');
                  });
  
                setTimeout(function() {
                  die = false;
  
                  setTimeout(function() {
                    test.deepEqual(['count', 'find'].sort(), results.sort());
                    client.close(done);
                  }, 1500);
                }, 1000);
              }, 3000);
            }, 1000);
          });
        });
      }
    });
  });
  