/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

'use strict';

var assert = require('assert');
var _ = require('lodash');

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

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 mathServiceAttrs = grpc.loadObject(
    mathService, common.defaultGrpcOptions).service;

/**
 * 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');
    });
  });
});
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 proto service', function() {
    assert.doesNotThrow(function() {
      server.addProtoService(mathService, dummyImpls);
    });
  });
  it('Should succeed with a single service attributes object', function() {
    assert.doesNotThrow(function() {
      server.addProtoService(mathServiceAttrs, dummyImpls);
    });
  });
});
describe('Server.prototype.addService', 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.addService(mathServiceAttrs, dummyImpls);
    });
  });
  it('Should fail with conflicting method names', function() {
    server.addService(mathServiceAttrs, dummyImpls);
    assert.throws(function() {
      server.addService(mathServiceAttrs, dummyImpls);
    });
  });
  it('Should allow method names as originally written', function() {
    var altDummyImpls = {
      'Div': function() {},
      'DivMany': function() {},
      'Fib': function() {},
      'Sum': function() {}
    };
    assert.doesNotThrow(function() {
      server.addProtoService(mathService, altDummyImpls);
    });
  });
  it('Should have a conflict between name variations', function() {
    /* This is really testing that both name variations are actually used,
       by checking that the method actually gets registered, for the
       corresponding function, in both cases */
    var altDummyImpls = {
      'Div': function() {},
      'DivMany': function() {},
      'Fib': function() {},
      'Sum': function() {}
    };
    server.addProtoService(mathService, altDummyImpls);
    assert.throws(function() {
      server.addProtoService(mathService, dummyImpls);
    });
  });
  it('Should fail if the server has been started', function() {
    server.start();
    assert.throws(function() {
      server.addService(mathServiceAttrs, dummyImpls);
    });
  });
  describe('Default handlers', function() {
    var client;
    beforeEach(function() {
      server.addService(mathServiceAttrs, {});
      var port = server.bind('localhost:0', server_insecure_creds);
      var Client = grpc.loadObject(mathService);
      client = new Client('localhost:' + port,
                          grpc.credentials.createInsecure());
      server.start();
    });
    it('should respond to a unary call with UNIMPLEMENTED', function(done) {
      client.div({divisor: 4, dividend: 3}, function(error, response) {
        assert(error);
        assert.strictEqual(error.code, grpc.status.UNIMPLEMENTED);
        done();
      });
    });
    it('should respond to a client stream with UNIMPLEMENTED', function(done) {
      var call = client.sum(function(error, respones) {
        assert(error);
        assert.strictEqual(error.code, grpc.status.UNIMPLEMENTED);
        done();
      });
      call.end();
    });
    it('should respond to a server stream with UNIMPLEMENTED', function(done) {
      var call = client.fib({limit: 5});
      call.on('data', function(value) {
        assert.fail('No messages expected');
      });
      call.on('error', function(err) {
        assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED);
        done();
      });
      call.on('error', function(status) { /* Do nothing */ });
    });
    it('should respond to a bidi call with UNIMPLEMENTED', function(done) {
      var call = client.divMany();
      call.on('data', function(value) {
        assert.fail('No messages expected');
      });
      call.on('error', function(err) {
        assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED);
        done();
      });
      call.on('error', function(status) { /* Do nothing */ });
      call.end();
    });
  });
});
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 = grpc.loadObject(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');
    var Client = grpc.loadObject(echo_service);
    server = new grpc.Server();
    server.addService(Client.service, {
      echo: function(call, callback) {
        callback(null, call.request);
      }
    });
    var port = server.bind('localhost:0', server_insecure_creds);
    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();
    });
  });
  it('Should convert an undefined argument to default values', function(done) {
    client.echo(undefined, function(error, response) {
      assert.ifError(error);
      assert.deepEqual(response, {value: '', value2: 0});
      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');
    var Client = grpc.loadObject(test_service);
    server = new grpc.Server();
    server.addService(Client.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);
    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({}, metadata, function(err, data) {
      assert.ifError(err);
    });
    call.on('metadata', function(metadata) {
      assert.deepEqual(metadata.get('key'), ['value']);
      done();
    });
  });
  it('with client stream call', function(done) {
    var call = client.clientStream(metadata, function(err, data) {
      assert.ifError(err);
    });
    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({}, metadata,
                            function(err, data) { assert.ifError(err); });
    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({}, dup_metadata,
                            function(err, data) {assert.ifError(err); });
    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 = grpc.loadObject(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('Server serialization failure handling', function() {
  function serializeFail(obj) {
    throw new Error('Serialization failed');
  }
  var client;
  var server;
  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: serializeFail
      },
      clientStream: {
        path: '/TestService/ClientStream',
        requestStream: true,
        responseStream: false,
        requestDeserialize: _.identity,
        responseSerialize: serializeFail
      },
      serverStream: {
        path: '/TestService/ServerStream',
        requestStream: false,
        responseStream: true,
        requestDeserialize: _.identity,
        responseSerialize: serializeFail
      },
      bidiStream: {
        path: '/TestService/BidiStream',
        requestStream: true,
        responseStream: true,
        requestDeserialize: _.identity,
        responseSerialize: serializeFail
      }
    };
    server = new grpc.Server();
    server.addService(malformed_test_service, {
      unary: function(call, cb) {
        cb(null, {});
      },
      clientStream: function(stream, cb) {
        stream.on('data', function() {/* Ignore requests */});
        stream.on('end', function() {
          cb(null, {});
        });
      },
      serverStream: function(stream) {
        stream.write({});
        stream.end();
      },
      bidiStream: function(stream) {
        stream.on('data', function() {
          // Ignore requests
          stream.write({});
        });
        stream.on('end', function() {
          stream.end();
        });
      }
    });
    var port = server.bind('localhost:0', server_insecure_creds);
    var Client = grpc.loadObject(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 Client;
  var client;
  var server;
  var port;
  before(function() {
    var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
    var test_service = test_proto.lookup('TestService');
    Client = grpc.loadObject(test_service);
    server = new grpc.Server();
    var trailer_metadata = new grpc.Metadata();
    trailer_metadata.add('trailer-present', 'yes');
    server.addService(Client.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 = 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.INTERNAL);
        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.INTERNAL);
        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.INTERNAL);
        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.INTERNAL);
        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();
      });
    });
    it('after the call has fully completed', function(done) {
      var peer;
      var call = client.unary({error: false}, function(err, data) {
        assert.ifError(err);
        setImmediate(function() {
          assert.strictEqual(peer, call.getPeer());
          done();
        });
      });
      peer = call.getPeer();
      assert.strictEqual(typeof peer, 'string');
    });
  });
});
describe('Call propagation', function() {
  var proxy;
  var proxy_impl;

  var Client;
  var client;
  var server;
  before(function() {
    var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
    var test_service = test_proto.lookup('TestService');
    server = new grpc.Server();
    Client = grpc.loadObject(test_service);
    server.addService(Client.service, {
      unary: function(call) {},
      clientStream: function(stream) {},
      serverStream: function(stream) {},
      bidiStream: function(stream) {}
    });
    var port = server.bind('localhost:0', server_insecure_creds);
    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);
      var call;
      proxy_impl.unary = function(parent, callback) {
        client.unary(parent.request, {parent: parent}, function(err, value) {
          try {
            assert(err);
            assert.strictEqual(err.code, grpc.status.CANCELLED);
          } finally {
            callback(err, value);
            done();
          }
        });
        call.cancel();
      };
      proxy.addService(Client.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());
      call = proxy_client.unary({}, function(err, value) { done(); });
    });
    it('With a client stream call', function(done) {
      done = multiDone(done, 2);
      var call;
      proxy_impl.clientStream = function(parent, callback) {
        client.clientStream({parent: parent}, function(err, value) {
          try {
            assert(err);
            assert.strictEqual(err.code, grpc.status.CANCELLED);
          } finally {
            callback(err, value);
            done();
          }
        });
        call.cancel();
      };
      proxy.addService(Client.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());
      call = proxy_client.clientStream(function(err, value) { done(); });
    });
    it('With a server stream call', function(done) {
      done = multiDone(done, 2);
      var call;
      proxy_impl.serverStream = function(parent) {
        var child = client.serverStream(parent.request, {parent: parent});
        child.on('data', function() {});
        child.on('error', function(err) {
          assert(err);
          assert.strictEqual(err.code, grpc.status.CANCELLED);
          done();
        });
        call.cancel();
      };
      proxy.addService(Client.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());
      call = proxy_client.serverStream({});
      call.on('data', function() {});
      call.on('error', function(err) {
        done();
      });
    });
    it('With a bidi stream call', function(done) {
      done = multiDone(done, 2);
      var call;
      proxy_impl.bidiStream = function(parent) {
        var child = client.bidiStream({parent: parent});
        child.on('data', function() {});
        child.on('error', function(err) {
          assert(err);
          assert.strictEqual(err.code, grpc.status.CANCELLED);
          done();
        });
        call.cancel();
      };
      proxy.addService(Client.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());
      call = proxy_client.bidiStream();
      call.on('data', function() {});
      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) {
        var options = {parent: parent, propagate_flags: deadline_flags};
        client.clientStream(options, function(err, value) {
          try {
            assert(err);
            assert(err.code === grpc.status.DEADLINE_EXCEEDED ||
                err.code === grpc.status.INTERNAL);
          } finally {
            callback(err, value);
            done();
          }
        });
      };
      proxy.addService(Client.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({deadline: deadline}, function(err, value) {
        done();
      });
    });
    it('With a bidi stream call', function(done) {
      done = multiDone(done, 2);
      proxy_impl.bidiStream = function(parent) {
        var child = client.bidiStream(
            {parent: parent, propagate_flags: deadline_flags});
        child.on('data', function() {});
        child.on('error', function(err) {
          assert(err);
          assert(err.code === grpc.status.DEADLINE_EXCEEDED ||
              err.code === grpc.status.INTERNAL);
          done();
        });
      };
      proxy.addService(Client.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({deadline: deadline});
      call.on('data', function() {});
      call.on('error', function(err) {
        done();
      });
    });
  });
});
describe('Cancelling surface client', function() {
  var client;
  var server;
  before(function() {
    server = new grpc.Server();
    server.addService(mathServiceAttrs, {
      '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.makeClientConstructor(mathServiceAttrs);
    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, grpc.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, grpc.status.CANCELLED);
      done();
    });
    call.cancel();
  });
  it('Should correctly cancel a server stream call', function(done) {
    var call = client.fib({'limit': 5});
    call.on('data', function() {});
    call.on('error', function(error) {
      assert.strictEqual(error.code, grpc.status.CANCELLED);
      done();
    });
    call.cancel();
  });
  it('Should correctly cancel a bidi stream call', function(done) {
    var call = client.divMany();
    call.on('data', function() {});
    call.on('error', function(error) {
      assert.strictEqual(error.code, grpc.status.CANCELLED);
      done();
    });
    call.cancel();
  });
  it('Should be idempotent', function(done) {
    var call = client.div({'divisor': 0, 'dividend': 0}, function(err, resp) {
      assert.strictEqual(err.code, grpc.status.CANCELLED);
      // Call asynchronously to try cancelling after call is fully completed
      setImmediate(function() {
        assert.doesNotThrow(function() {
          call.cancel();
        });
        done();
      });
    });
    call.cancel();
  });
});
describe('Client reconnect', function() {
  var server;
  var Client;
  var client;
  var port;
  beforeEach(function() {
    var test_proto = ProtoBuf.loadProtoFile(__dirname + '/echo_service.proto');
    var echo_service = test_proto.lookup('EchoService');
    Client = grpc.loadObject(echo_service);
    server = new grpc.Server();
    server.addService(Client.service, {
      echo: function(call, callback) {
        callback(null, call.request);
      }
    });
    port = server.bind('localhost:0', server_insecure_creds);
    client = new Client('localhost:' + port, grpc.credentials.createInsecure());
    server.start();
  });
  afterEach(function() {
    server.forceShutdown();
  });
  it('should reconnect after server restart', function(done) {
    client.echo({value: 'test value', value2: 3}, function(error, response) {
      assert.ifError(error);
      assert.deepEqual(response, {value: 'test value', value2: 3});
      server.tryShutdown(function() {
        server = new grpc.Server();
        server.addService(Client.service, {
          echo: function(call, callback) {
            callback(null, call.request);
          }
        });
        server.bind('localhost:' + port, server_insecure_creds);
        server.start();

        /* We create a new client, that will not throw an error if the server
         * is not immediately available. Instead, it will wait for the server
         * to be available, then the call will complete. Once this happens, the
         * original client should be able to make a new call and connect to the
         * restarted server without having the call fail due to connection
         * errors. */
        var client2 = new Client('localhost:' + port,
                                 grpc.credentials.createInsecure());
        client2.echo({value: 'test', value2: 3}, function(error, response) {
          assert.ifError(error);
          client.echo(undefined, function(error, response) {
            if (error) {
              console.log(error);
            }
            assert.ifError(error);
            assert.deepEqual(response, {value: '', value2: 0});
            done();
          });
        });
      });
    });
  });
});
