/*
 *
 * Copyright 2015, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

'use strict';

var assert = require('assert');

var surface_client = require('../src/client.js');

var ProtoBuf = require('protobufjs');

var grpc = require('..');

var math_proto = ProtoBuf.loadProtoFile(__dirname +
    '/../../proto/math/math.proto');

var mathService = math_proto.lookup('math.Math');

var _ = require('lodash');

/**
 * This is used for testing functions with multiple asynchronous calls that
 * can happen in different orders. This should be passed the number of async
 * function invocations that can occur last, and each of those should call this
 * function's return value
 * @param {function()} done The function that should be called when a test is
 *     complete.
 * @param {number} count The number of calls to the resulting function if the
 *     test passes.
 * @return {function()} The function that should be called at the end of each
 *     sequence of asynchronous functions.
 */
function multiDone(done, count) {
  return function() {
    count -= 1;
    if (count <= 0) {
      done();
    }
  };
}

var server_insecure_creds = grpc.ServerCredentials.createInsecure();

describe('File loader', function() {
  it('Should load a proto file by default', function() {
    assert.doesNotThrow(function() {
      grpc.load(__dirname + '/test_service.proto');
    });
  });
  it('Should load a proto file with the proto format', function() {
    assert.doesNotThrow(function() {
      grpc.load(__dirname + '/test_service.proto', 'proto');
    });
  });
  it('Should load a json file with the json format', function() {
    assert.doesNotThrow(function() {
      grpc.load(__dirname + '/test_service.json', 'json');
    });
  });
  it('Should fail to load a file with an unknown format', function() {
    assert.throws(function() {
      grpc.load(__dirname + '/test_service.proto', 'fake_format');
    });
  });
});
describe('surface Server', function() {
  var server;
  beforeEach(function() {
    server = new grpc.Server();
  });
  afterEach(function() {
    server.forceShutdown();
  });
  it('should error if started twice', function() {
    server.start();
    assert.throws(function() {
      server.start();
    });
  });
  it('should error if a port is bound after the server starts', function() {
    server.start();
    assert.throws(function() {
      server.bind('localhost:0', grpc.ServerCredentials.createInsecure());
    });
  });
  it('should successfully shutdown if tryShutdown is called', function(done) {
    server.start();
    server.tryShutdown(done);
  });
});
describe('Server.prototype.addProtoService', function() {
  var server;
  var dummyImpls = {
    'div': function() {},
    'divMany': function() {},
    'fib': function() {},
    'sum': function() {}
  };
  beforeEach(function() {
    server = new grpc.Server();
  });
  afterEach(function() {
    server.forceShutdown();
  });
  it('Should succeed with a single service', function() {
    assert.doesNotThrow(function() {
      server.addProtoService(mathService, dummyImpls);
    });
  });
  it('Should fail with conflicting method names', function() {
    server.addProtoService(mathService, dummyImpls);
    assert.throws(function() {
      server.addProtoService(mathService, dummyImpls);
    });
  });
  it('Should fail with missing handlers', function() {
    assert.throws(function() {
      server.addProtoService(mathService, {
        'div': function() {},
        'divMany': function() {},
        'fib': function() {}
      });
    }, /math.Math.Sum/);
  });
  it('Should fail if the server has been started', function() {
    server.start();
    assert.throws(function() {
      server.addProtoService(mathService, dummyImpls);
    });
  });
});
describe('Client constructor building', function() {
  var illegal_service_attrs = {
    $method : {
      path: '/illegal/$method',
      requestStream: false,
      responseStream: false,
      requestSerialize: _.identity,
      requestDeserialize: _.identity,
      responseSerialize: _.identity,
      responseDeserialize: _.identity
    }
  };
  it('Should reject method names starting with $', function() {
    assert.throws(function() {
      grpc.makeGenericClientConstructor(illegal_service_attrs);
    }, /\$/);
  });
});
describe('waitForClientReady', function() {
  var server;
  var port;
  var Client;
  var client;
  before(function() {
    server = new grpc.Server();
    port = server.bind('localhost:0', grpc.ServerCredentials.createInsecure());
    server.start();
    Client = surface_client.makeProtobufClientConstructor(mathService);
  });
  beforeEach(function() {
    client = new Client('localhost:' + port, grpc.credentials.createInsecure());
  });
  after(function() {
    server.forceShutdown();
  });
  it('should complete when called alone', function(done) {
    grpc.waitForClientReady(client, Infinity, function(error) {
      assert.ifError(error);
      done();
    });
  });
  it('should complete when a call is initiated', function(done) {
    grpc.waitForClientReady(client, Infinity, function(error) {
      assert.ifError(error);
      done();
    });
    var call = client.div({}, function(err, response) {});
    call.cancel();
  });
  it('should complete if called more than once', function(done) {
    done = multiDone(done, 2);
    grpc.waitForClientReady(client, Infinity, function(error) {
      assert.ifError(error);
      done();
    });
    grpc.waitForClientReady(client, Infinity, function(error) {
      assert.ifError(error);
      done();
    });
  });
  it('should complete if called when already ready', function(done) {
    grpc.waitForClientReady(client, Infinity, function(error) {
      assert.ifError(error);
      grpc.waitForClientReady(client, Infinity, function(error) {
        assert.ifError(error);
        done();
      });
    });
  });
  it('should time out if the server does not exist', function(done) {
    var bad_client = new Client('nonexistent_hostname',
                                grpc.credentials.createInsecure());
    var deadline = new Date();
    deadline.setSeconds(deadline.getSeconds() + 1);
    grpc.waitForClientReady(bad_client, deadline, function(error) {
      assert(error);
      done();
    });
  });
});
describe('Echo service', function() {
  var server;
  var client;
  before(function() {
    var test_proto = ProtoBuf.loadProtoFile(__dirname + '/echo_service.proto');
    var echo_service = test_proto.lookup('EchoService');
    server = new grpc.Server();
    server.addProtoService(echo_service, {
      echo: function(call, callback) {
        callback(null, call.request);
      }
    });
    var port = server.bind('localhost:0', server_insecure_creds);
    var Client = surface_client.makeProtobufClientConstructor(echo_service);
    client = new Client('localhost:' + port, grpc.credentials.createInsecure());
    server.start();
  });
  after(function() {
    server.forceShutdown();
  });
  it('should echo the recieved message directly', function(done) {
    client.echo({value: 'test value', value2: 3}, function(error, response) {
      assert.ifError(error);
      assert.deepEqual(response, {value: 'test value', value2: 3});
      done();
    });
  });
});
describe('Generic client and server', function() {
  function toString(val) {
    return val.toString();
  }
  function toBuffer(str) {
    return new Buffer(str);
  }
  var string_service_attrs = {
    'capitalize' : {
      path: '/string/capitalize',
      requestStream: false,
      responseStream: false,
      requestSerialize: toBuffer,
      requestDeserialize: toString,
      responseSerialize: toBuffer,
      responseDeserialize: toString
    }
  };
  describe('String client and server', function() {
    var client;
    var server;
    before(function() {
      server = new grpc.Server();
      server.addService(string_service_attrs, {
        capitalize: function(call, callback) {
          callback(null, _.capitalize(call.request));
        }
      });
      var port = server.bind('localhost:0', server_insecure_creds);
      server.start();
      var Client = grpc.makeGenericClientConstructor(string_service_attrs);
      client = new Client('localhost:' + port,
                          grpc.credentials.createInsecure());
    });
    after(function() {
      server.forceShutdown();
    });
    it('Should respond with a capitalized string', function(done) {
      client.capitalize('abc', function(err, response) {
        assert.ifError(err);
        assert.strictEqual(response, 'Abc');
        done();
      });
    });
  });
});
describe('Server-side getPeer', function() {
  function toString(val) {
    return val.toString();
  }
  function toBuffer(str) {
    return new Buffer(str);
  }
  var string_service_attrs = {
    'getPeer' : {
      path: '/string/getPeer',
      requestStream: false,
      responseStream: false,
      requestSerialize: toBuffer,
      requestDeserialize: toString,
      responseSerialize: toBuffer,
      responseDeserialize: toString
    }
  };
  var client;
  var server;
  before(function() {
    server = new grpc.Server();
    server.addService(string_service_attrs, {
      getPeer: function(call, callback) {
        try {
          callback(null, call.getPeer());
        } catch (e) {
          call.emit('error', e);
        }
      }
    });
    var port = server.bind('localhost:0', server_insecure_creds);
    server.start();
    var Client = grpc.makeGenericClientConstructor(string_service_attrs);
    client = new Client('localhost:' + port,
                        grpc.credentials.createInsecure());
  });
  after(function() {
    server.forceShutdown();
  });
  it('should respond with a string representing the client', function(done) {
    client.getPeer('', function(err, response) {
      assert.ifError(err);
      // We don't expect a specific value, just that it worked without error
      done();
    });
  });
});
describe('Echo metadata', function() {
  var client;
  var server;
  var metadata;
  before(function() {
    var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
    var test_service = test_proto.lookup('TestService');
    server = new grpc.Server();
    server.addProtoService(test_service, {
      unary: function(call, cb) {
        call.sendMetadata(call.metadata);
        cb(null, {});
      },
      clientStream: function(stream, cb){
        stream.on('data', function(data) {});
        stream.on('end', function() {
          stream.sendMetadata(stream.metadata);
          cb(null, {});
        });
      },
      serverStream: function(stream) {
        stream.sendMetadata(stream.metadata);
        stream.end();
      },
      bidiStream: function(stream) {
        stream.on('data', function(data) {});
        stream.on('end', function() {
          stream.sendMetadata(stream.metadata);
          stream.end();
        });
      }
    });
    var port = server.bind('localhost:0', server_insecure_creds);
    var Client = surface_client.makeProtobufClientConstructor(test_service);
    client = new Client('localhost:' + port, grpc.credentials.createInsecure());
    server.start();
    metadata = new grpc.Metadata();
    metadata.set('key', 'value');
  });
  after(function() {
    server.forceShutdown();
  });
  it('with unary call', function(done) {
    var call = client.unary({}, function(err, data) {
      assert.ifError(err);
    }, metadata);
    call.on('metadata', function(metadata) {
      assert.deepEqual(metadata.get('key'), ['value']);
      done();
    });
  });
  it('with client stream call', function(done) {
    var call = client.clientStream(function(err, data) {
      assert.ifError(err);
    }, metadata);
    call.on('metadata', function(metadata) {
      assert.deepEqual(metadata.get('key'), ['value']);
      done();
    });
    call.end();
  });
  it('with server stream call', function(done) {
    var call = client.serverStream({}, metadata);
    call.on('data', function() {});
    call.on('metadata', function(metadata) {
      assert.deepEqual(metadata.get('key'), ['value']);
      done();
    });
  });
  it('with bidi stream call', function(done) {
    var call = client.bidiStream(metadata);
    call.on('data', function() {});
    call.on('metadata', function(metadata) {
      assert.deepEqual(metadata.get('key'), ['value']);
      done();
    });
    call.end();
  });
  it('shows the correct user-agent string', function(done) {
    var version = require('../../../package.json').version;
    var call = client.unary({}, function(err, data) { assert.ifError(err); },
                            metadata);
    call.on('metadata', function(metadata) {
      assert(_.startsWith(metadata.get('user-agent')[0],
                          'grpc-node/' + version));
      done();
    });
  });
  it('properly handles duplicate values', function(done) {
    var dup_metadata = metadata.clone();
    dup_metadata.add('key', 'value2');
    var call = client.unary({}, function(err, data) {assert.ifError(err); },
                            dup_metadata);
    call.on('metadata', function(resp_metadata) {
      // Two arrays are equal iff their symmetric difference is empty
      assert.deepEqual(_.xor(dup_metadata.get('key'), resp_metadata.get('key')),
                       []);
      done();
    });
  });
});
describe('Client malformed response handling', function() {
  var server;
  var client;
  var badArg = new Buffer([0xFF]);
  before(function() {
    var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
    var test_service = test_proto.lookup('TestService');
    var malformed_test_service = {
      unary: {
        path: '/TestService/Unary',
        requestStream: false,
        responseStream: false,
        requestDeserialize: _.identity,
        responseSerialize: _.identity
      },
      clientStream: {
        path: '/TestService/ClientStream',
        requestStream: true,
        responseStream: false,
        requestDeserialize: _.identity,
        responseSerialize: _.identity
      },
      serverStream: {
        path: '/TestService/ServerStream',
        requestStream: false,
        responseStream: true,
        requestDeserialize: _.identity,
        responseSerialize: _.identity
      },
      bidiStream: {
        path: '/TestService/BidiStream',
        requestStream: true,
        responseStream: true,
        requestDeserialize: _.identity,
        responseSerialize: _.identity
      }
    };
    server = new grpc.Server();
    server.addService(malformed_test_service, {
      unary: function(call, cb) {
        cb(null, badArg);
      },
      clientStream: function(stream, cb) {
        stream.on('data', function() {/* Ignore requests */});
        stream.on('end', function() {
          cb(null, badArg);
        });
      },
      serverStream: function(stream) {
        stream.write(badArg);
        stream.end();
      },
      bidiStream: function(stream) {
        stream.on('data', function() {
          // Ignore requests
          stream.write(badArg);
        });
        stream.on('end', function() {
          stream.end();
        });
      }
    });
    var port = server.bind('localhost:0', server_insecure_creds);
    var Client = surface_client.makeProtobufClientConstructor(test_service);
    client = new Client('localhost:' + port, grpc.credentials.createInsecure());
    server.start();
  });
  after(function() {
    server.forceShutdown();
  });
  it('should get an INTERNAL status with a unary call', function(done) {
    client.unary({}, function(err, data) {
      assert(err);
      assert.strictEqual(err.code, grpc.status.INTERNAL);
      done();
    });
  });
  it('should get an INTERNAL status with a client stream call', function(done) {
    var call = client.clientStream(function(err, data) {
      assert(err);
      assert.strictEqual(err.code, grpc.status.INTERNAL);
      done();
    });
    call.write({});
    call.end();
  });
  it('should get an INTERNAL status with a server stream call', function(done) {
    var call = client.serverStream({});
    call.on('data', function(){});
    call.on('error', function(err) {
      assert.strictEqual(err.code, grpc.status.INTERNAL);
      done();
    });
  });
  it('should get an INTERNAL status with a bidi stream call', function(done) {
    var call = client.bidiStream();
    call.on('data', function(){});
    call.on('error', function(err) {
      assert.strictEqual(err.code, grpc.status.INTERNAL);
      done();
    });
    call.write({});
    call.end();
  });
});
describe('Other conditions', function() {
  var test_service;
  var Client;
  var client;
  var server;
  var port;
  before(function() {
    var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
    test_service = test_proto.lookup('TestService');
    server = new grpc.Server();
    var trailer_metadata = new grpc.Metadata();
    trailer_metadata.add('trailer-present', 'yes');
    server.addProtoService(test_service, {
      unary: function(call, cb) {
        var req = call.request;
        if (req.error) {
          cb({code: grpc.status.UNKNOWN,
              details: 'Requested error'}, null, trailer_metadata);
        } else {
          cb(null, {count: 1}, trailer_metadata);
        }
      },
      clientStream: function(stream, cb){
        var count = 0;
        var errored;
        stream.on('data', function(data) {
          if (data.error) {
            errored = true;
            cb(new Error('Requested error'), null, trailer_metadata);
          } else {
            count += 1;
          }
        });
        stream.on('end', function() {
          if (!errored) {
            cb(null, {count: count}, trailer_metadata);
          }
        });
      },
      serverStream: function(stream) {
        var req = stream.request;
        if (req.error) {
          var err = {code: grpc.status.UNKNOWN,
                     details: 'Requested error'};
          err.metadata = trailer_metadata;
          stream.emit('error', err);
        } else {
          for (var i = 0; i < 5; i++) {
            stream.write({count: i});
          }
          stream.end(trailer_metadata);
        }
      },
      bidiStream: function(stream) {
        var count = 0;
        stream.on('data', function(data) {
          if (data.error) {
            var err = new Error('Requested error');
            err.metadata = trailer_metadata.clone();
            err.metadata.add('count', '' + count);
            stream.emit('error', err);
          } else {
            stream.write({count: count});
            count += 1;
          }
        });
        stream.on('end', function() {
          stream.end(trailer_metadata);
        });
      }
    });
    port = server.bind('localhost:0', server_insecure_creds);
    Client = surface_client.makeProtobufClientConstructor(test_service);
    client = new Client('localhost:' + port, grpc.credentials.createInsecure());
    server.start();
  });
  after(function() {
    server.forceShutdown();
  });
  it('channel.getTarget should be available', function() {
    assert.strictEqual(typeof grpc.getClientChannel(client).getTarget(),
                       'string');
  });
  it('client should be able to pause and resume a stream', function(done) {
    var call = client.bidiStream();
    call.on('data', function(data) {
      assert(data.count < 3);
      call.pause();
      setTimeout(function() {
        call.resume();
      }, 10);
    });
    call.on('end', function() {
      done();
    });
    call.write({});
    call.write({});
    call.write({});
    call.end();
  });
  describe('Server recieving bad input', function() {
    var misbehavingClient;
    var badArg = new Buffer([0xFF]);
    before(function() {
      var test_service_attrs = {
        unary: {
          path: '/TestService/Unary',
          requestStream: false,
          responseStream: false,
          requestSerialize: _.identity,
          responseDeserialize: _.identity
        },
        clientStream: {
          path: '/TestService/ClientStream',
          requestStream: true,
          responseStream: false,
          requestSerialize: _.identity,
          responseDeserialize: _.identity
        },
        serverStream: {
          path: '/TestService/ServerStream',
          requestStream: false,
          responseStream: true,
          requestSerialize: _.identity,
          responseDeserialize: _.identity
        },
        bidiStream: {
          path: '/TestService/BidiStream',
          requestStream: true,
          responseStream: true,
          requestSerialize: _.identity,
          responseDeserialize: _.identity
        }
      };
      var Client = surface_client.makeClientConstructor(test_service_attrs,
                                                        'TestService');
      misbehavingClient = new Client('localhost:' + port,
                                     grpc.credentials.createInsecure());
    });
    it('should respond correctly to a unary call', function(done) {
      misbehavingClient.unary(badArg, function(err, data) {
        assert(err);
        assert.strictEqual(err.code, grpc.status.INVALID_ARGUMENT);
        done();
      });
    });
    it('should respond correctly to a client stream', function(done) {
      var call = misbehavingClient.clientStream(function(err, data) {
        assert(err);
        assert.strictEqual(err.code, grpc.status.INVALID_ARGUMENT);
        done();
      });
      call.write(badArg);
      // TODO(mlumish): Remove call.end()
      call.end();
    });
    it('should respond correctly to a server stream', function(done) {
      var call = misbehavingClient.serverStream(badArg);
      call.on('data', function(data) {
        assert.fail(data, null, 'Unexpected data', '===');
      });
      call.on('error', function(err) {
        assert.strictEqual(err.code, grpc.status.INVALID_ARGUMENT);
        done();
      });
    });
    it('should respond correctly to a bidi stream', function(done) {
      var call = misbehavingClient.bidiStream();
      call.on('data', function(data) {
        assert.fail(data, null, 'Unexpected data', '===');
      });
      call.on('error', function(err) {
        assert.strictEqual(err.code, grpc.status.INVALID_ARGUMENT);
        done();
      });
      call.write(badArg);
      // TODO(mlumish): Remove call.end()
      call.end();
    });
  });
  describe('Trailing metadata', function() {
    it('should be present when a unary call succeeds', function(done) {
      var call = client.unary({error: false}, function(err, data) {
        assert.ifError(err);
      });
      call.on('status', function(status) {
        assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
        done();
      });
    });
    it('should be present when a unary call fails', function(done) {
      var call = client.unary({error: true}, function(err, data) {
        assert(err);
      });
      call.on('status', function(status) {
        assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
        done();
      });
    });
    it('should be present when a client stream call succeeds', function(done) {
      var call = client.clientStream(function(err, data) {
        assert.ifError(err);
      });
      call.write({error: false});
      call.write({error: false});
      call.end();
      call.on('status', function(status) {
        assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
        done();
      });
    });
    it('should be present when a client stream call fails', function(done) {
      var call = client.clientStream(function(err, data) {
        assert(err);
      });
      call.write({error: false});
      call.write({error: true});
      call.end();
      call.on('status', function(status) {
        assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
        done();
      });
    });
    it('should be present when a server stream call succeeds', function(done) {
      var call = client.serverStream({error: false});
      call.on('data', function(){});
      call.on('status', function(status) {
        assert.strictEqual(status.code, grpc.status.OK);
        assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
        done();
      });
    });
    it('should be present when a server stream call fails', function(done) {
      var call = client.serverStream({error: true});
      call.on('data', function(){});
      call.on('error', function(error) {
        assert.deepEqual(error.metadata.get('trailer-present'), ['yes']);
        done();
      });
    });
    it('should be present when a bidi stream succeeds', function(done) {
      var call = client.bidiStream();
      call.write({error: false});
      call.write({error: false});
      call.end();
      call.on('data', function(){});
      call.on('status', function(status) {
        assert.strictEqual(status.code, grpc.status.OK);
        assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
        done();
      });
    });
    it('should be present when a bidi stream fails', function(done) {
      var call = client.bidiStream();
      call.write({error: false});
      call.write({error: true});
      call.end();
      call.on('data', function(){});
      call.on('error', function(error) {
        assert.deepEqual(error.metadata.get('trailer-present'), ['yes']);
        done();
      });
    });
  });
  describe('Error object should contain the status', function() {
    it('for a unary call', function(done) {
      client.unary({error: true}, function(err, data) {
        assert(err);
        assert.strictEqual(err.code, grpc.status.UNKNOWN);
        assert.strictEqual(err.message, 'Requested error');
        done();
      });
    });
    it('for a client stream call', function(done) {
      var call = client.clientStream(function(err, data) {
        assert(err);
        assert.strictEqual(err.code, grpc.status.UNKNOWN);
        assert.strictEqual(err.message, 'Requested error');
        done();
      });
      call.write({error: false});
      call.write({error: true});
      call.end();
    });
    it('for a server stream call', function(done) {
      var call = client.serverStream({error: true});
      call.on('data', function(){});
      call.on('error', function(error) {
        assert.strictEqual(error.code, grpc.status.UNKNOWN);
        assert.strictEqual(error.message, 'Requested error');
        done();
      });
    });
    it('for a bidi stream call', function(done) {
      var call = client.bidiStream();
      call.write({error: false});
      call.write({error: true});
      call.end();
      call.on('data', function(){});
      call.on('error', function(error) {
        assert.strictEqual(error.code, grpc.status.UNKNOWN);
        assert.strictEqual(error.message, 'Requested error');
        done();
      });
    });
  });
  describe('call.getPeer should return the peer', function() {
    it('for a unary call', function(done) {
      var call = client.unary({error: false}, function(err, data) {
        assert.ifError(err);
        done();
      });
      assert.strictEqual(typeof call.getPeer(), 'string');
    });
    it('for a client stream call', function(done) {
      var call = client.clientStream(function(err, data) {
        assert.ifError(err);
        done();
      });
      assert.strictEqual(typeof call.getPeer(), 'string');
      call.write({error: false});
      call.end();
    });
    it('for a server stream call', function(done) {
      var call = client.serverStream({error: false});
      assert.strictEqual(typeof call.getPeer(), 'string');
      call.on('data', function(){});
      call.on('status', function(status) {
        assert.strictEqual(status.code, grpc.status.OK);
        done();
      });
    });
    it('for a bidi stream call', function(done) {
      var call = client.bidiStream();
      assert.strictEqual(typeof call.getPeer(), 'string');
      call.write({error: false});
      call.end();
      call.on('data', function(){});
      call.on('status', function(status) {
        done();
      });
    });
  });
});
describe('Call propagation', function() {
  var proxy;
  var proxy_impl;

  var test_service;
  var Client;
  var client;
  var server;
  before(function() {
    var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
    test_service = test_proto.lookup('TestService');
    server = new grpc.Server();
    server.addProtoService(test_service, {
      unary: function(call) {},
      clientStream: function(stream) {},
      serverStream: function(stream) {},
      bidiStream: function(stream) {}
    });
    var port = server.bind('localhost:0', server_insecure_creds);
    Client = surface_client.makeProtobufClientConstructor(test_service);
    client = new Client('localhost:' + port, grpc.credentials.createInsecure());
    server.start();
  });
  after(function() {
    server.forceShutdown();
  });
  beforeEach(function() {
    proxy = new grpc.Server();
    proxy_impl = {
      unary: function(call) {},
      clientStream: function(stream) {},
      serverStream: function(stream) {},
      bidiStream: function(stream) {}
    };
  });
  afterEach(function() {
    proxy.forceShutdown();
  });
  describe('Cancellation', function() {
    it('With a unary call', function(done) {
      done = multiDone(done, 2);
      proxy_impl.unary = function(parent, callback) {
        client.unary(parent.request, function(err, value) {
          try {
            assert(err);
            assert.strictEqual(err.code, grpc.status.CANCELLED);
          } finally {
            callback(err, value);
            done();
          }
        }, null, {parent: parent});
        call.cancel();
      };
      proxy.addProtoService(test_service, proxy_impl);
      var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
      proxy.start();
      var proxy_client = new Client('localhost:' + proxy_port,
                                    grpc.credentials.createInsecure());
      var call = proxy_client.unary({}, function(err, value) {
        done();
      });
    });
    it('With a client stream call', function(done) {
      done = multiDone(done, 2);
      proxy_impl.clientStream = function(parent, callback) {
        client.clientStream(function(err, value) {
          try {
            assert(err);
            assert.strictEqual(err.code, grpc.status.CANCELLED);
          } finally {
            callback(err, value);
            done();
          }
        }, null, {parent: parent});
        call.cancel();
      };
      proxy.addProtoService(test_service, proxy_impl);
      var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
      proxy.start();
      var proxy_client = new Client('localhost:' + proxy_port,
                                    grpc.credentials.createInsecure());
      var call = proxy_client.clientStream(function(err, value) {
        done();
      });
    });
    it('With a server stream call', function(done) {
      done = multiDone(done, 2);
      proxy_impl.serverStream = function(parent) {
        var child = client.serverStream(parent.request, null,
                                        {parent: parent});
        child.on('error', function(err) {
          assert(err);
          assert.strictEqual(err.code, grpc.status.CANCELLED);
          done();
        });
        call.cancel();
      };
      proxy.addProtoService(test_service, proxy_impl);
      var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
      proxy.start();
      var proxy_client = new Client('localhost:' + proxy_port,
                                    grpc.credentials.createInsecure());
      var call = proxy_client.serverStream({});
      call.on('error', function(err) {
        done();
      });
    });
    it('With a bidi stream call', function(done) {
      done = multiDone(done, 2);
      proxy_impl.bidiStream = function(parent) {
        var child = client.bidiStream(null, {parent: parent});
        child.on('error', function(err) {
          assert(err);
          assert.strictEqual(err.code, grpc.status.CANCELLED);
          done();
        });
        call.cancel();
      };
      proxy.addProtoService(test_service, proxy_impl);
      var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
      proxy.start();
      var proxy_client = new Client('localhost:' + proxy_port,
                                    grpc.credentials.createInsecure());
      var call = proxy_client.bidiStream();
      call.on('error', function(err) {
        done();
      });
    });
  });
  describe('Deadline', function() {
    /* jshint bitwise:false */
    var deadline_flags = (grpc.propagate.DEFAULTS &
        ~grpc.propagate.CANCELLATION);
    it('With a client stream call', function(done) {
      done = multiDone(done, 2);
      proxy_impl.clientStream = function(parent, callback) {
        client.clientStream(function(err, value) {
          try {
            assert(err);
            assert(err.code === grpc.status.DEADLINE_EXCEEDED ||
                err.code === grpc.status.INTERNAL);
          } finally {
            callback(err, value);
            done();
          }
        }, null, {parent: parent, propagate_flags: deadline_flags});
      };
      proxy.addProtoService(test_service, proxy_impl);
      var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
      proxy.start();
      var proxy_client = new Client('localhost:' + proxy_port,
                                    grpc.credentials.createInsecure());
      var deadline = new Date();
      deadline.setSeconds(deadline.getSeconds() + 1);
      proxy_client.clientStream(function(err, value) {
        done();
      }, null, {deadline: deadline});
    });
    it('With a bidi stream call', function(done) {
      done = multiDone(done, 2);
      proxy_impl.bidiStream = function(parent) {
        var child = client.bidiStream(
            null, {parent: parent, propagate_flags: deadline_flags});
        child.on('error', function(err) {
          assert(err);
          assert(err.code === grpc.status.DEADLINE_EXCEEDED ||
              err.code === grpc.status.INTERNAL);
          done();
        });
      };
      proxy.addProtoService(test_service, proxy_impl);
      var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
      proxy.start();
      var proxy_client = new Client('localhost:' + proxy_port,
                                    grpc.credentials.createInsecure());
      var deadline = new Date();
      deadline.setSeconds(deadline.getSeconds() + 1);
      var call = proxy_client.bidiStream(null, {deadline: deadline});
      call.on('error', function(err) {
        done();
      });
    });
  });
});
describe('Cancelling surface client', function() {
  var client;
  var server;
  before(function() {
    server = new grpc.Server();
    server.addProtoService(mathService, {
      'div': function(stream) {},
      'divMany': function(stream) {},
      'fib': function(stream) {},
      'sum': function(stream) {}
    });
    var port = server.bind('localhost:0', server_insecure_creds);
    var Client = surface_client.makeProtobufClientConstructor(mathService);
    client = new Client('localhost:' + port, grpc.credentials.createInsecure());
    server.start();
  });
  after(function() {
    server.forceShutdown();
  });
  it('Should correctly cancel a unary call', function(done) {
    var call = client.div({'divisor': 0, 'dividend': 0}, function(err, resp) {
      assert.strictEqual(err.code, surface_client.status.CANCELLED);
      done();
    });
    call.cancel();
  });
  it('Should correctly cancel a client stream call', function(done) {
    var call = client.sum(function(err, resp) {
      assert.strictEqual(err.code, surface_client.status.CANCELLED);
      done();
    });
    call.cancel();
  });
  it('Should correctly cancel a server stream call', function(done) {
    var call = client.fib({'limit': 5});
    call.on('error', function(error) {
      assert.strictEqual(error.code, surface_client.status.CANCELLED);
      done();
    });
    call.cancel();
  });
  it('Should correctly cancel a bidi stream call', function(done) {
    var call = client.divMany();
    call.on('error', function(error) {
      assert.strictEqual(error.code, surface_client.status.CANCELLED);
      done();
    });
    call.cancel();
  });
});
