// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

var test = require('prova');
var Client = require('../../src/rpc/client.js');
var context = require('../../src/context');
var createSignature = require('../../src/vdl/create-signature');
var createMockProxy = require('./mock-proxy');
var vdl = require('../../src/vdl');
var byteUtil = require('../../src/vdl/byte-util');
var vom = require('../../src/vom');
var hexVom = require('../../src/lib/hex-vom');
var vtrace = require('../../src/vtrace');
var app = require('../../src/gen-vdl/v.io/x/ref/services/wspr/internal/app');
var SharedContextKeys = require('../../src/runtime/shared-context-keys');

var mockService = {
  tripleArgMethod: function(ctx, serverCall, a, b, c) {},
  singleArgMethod: function(ctx, serverCall, a) {},
  lyingBoolMethod: function(ctx, serverCall) {},
};
var mockServiceDescs = [
  {
    methods: [
      {
        name: 'LyingBoolMethod',
        inArgs: [],
        outArgs: [
          {
            name: 'Is VanadiumRPCRequest not Bool',
            type: vdl.types.BOOL
          }
        ]
      }
    ]
  }
];

var mockSignature = createSignature(mockService, mockServiceDescs);
var mockRuntime = {
  _controller: null,
};

function testContext() {
  var ctx = new context.Context();
  ctx = vtrace.withNewStore(ctx);
  ctx = vtrace.withNewTrace(ctx);
  ctx = ctx.withValue(SharedContextKeys.RUNTIME, mockRuntime);
  return ctx;
}

var mockProxy = createMockProxy(function(data, type) {
  return vom.decode(byteUtil.hex2Bytes(data)).then(function(decodedData) {
    var response = new app.RpcResponse();

    if (decodedData instanceof app.RpcRequest &&
        decodedData.method === 'Signature') {
      response.outArgs = [mockSignature];
    } else {
      // Take the first arg and return it in a result list.
      response.outArgs = [decodedData];
    }
    return hexVom.encode(response);
  });
});

test('creating instances', function(assert) {
  assert.equal(typeof Client, 'function');
  assert.ok(Client() instanceof Client); // jshint ignore:line
  assert.end();
});

test('Test that bindTo fails on missing context - using callbacks',
  function(assert) {
  var client = new Client(mockProxy);

  client.bindTo('service-name', function(err) {
    assert.ok(err, 'expected to error on no context');
    assert.end();
  });
});

test('Test that bindTo fails on missing context - using promises',
  function(assert) {
  var client = new Client(mockProxy);

  client
  .bindTo('service-name')
  .then(function() {
    assert.fail('should not succeed');
    assert.end();
  }, function(err) {
    assert.ok(err, 'expected to error on no context');
    assert.end();
  })
  .catch(assert.end);
});


function validateBoundService(assert, boundService) {
    var expectedMethods = Object.keys(mockService).sort();
    assert.deepEqual(
      Object.keys(boundService).sort(),
      expectedMethods,
      'bound service methods don\'t match expectation');
    for (var key in boundService) { // jshint ignore:line
      assert.notOk(key in expectedMethods,
        'key ' + key + ' not expect on service');
      assert.ok(typeof boundService[key] === 'function',
        'non-function key on bound service ' + key);
    }

    assert.ok(boundService.__signature);
}

test('Test that correct bindTo call succeeds - using callbacks',
  function(assert) {
  var client = new Client(mockProxy);
  var ctx = testContext();

  client.bindTo(ctx, 'service-name', function(err, boundService) {
    assert.notOk(err, 'no error expected');
    validateBoundService(assert, boundService);
    assert.end();
  });
});

test('Test that correct bindTo call succeeds - using promises',
  function(assert) {
  var client = new Client(mockProxy);
  var ctx = testContext();

  client.bindTo(ctx, 'service-name')
    .then(function(boundService) {
      validateBoundService(assert, boundService);
      assert.end();
    })
    .catch(function(err) {
    assert.notOk(err, 'no error expected');
    assert.end();
  });
});

test('Test that service.method() returns the correct result - using callbacks',
  function(assert) {
  var client = new Client(mockProxy);
  var ctx = testContext();

  client.bindTo(ctx, 'service-name', onservice);

  function onservice(err, service) {
    assert.error(err);

    service.tripleArgMethod(ctx, 3, 'X', null, onmethod);
  }

  function onmethod(err, result) {
    assert.error(err);
    assert.equal(result.method, 'TripleArgMethod');
    assert.equal(result.numInArgs, 3);
    assert.end();
  }
});

test('Test that service.method() returns the correct result - using promises',
  function(assert) {
  var client = new Client(mockProxy);
  var ctx = testContext();

  client
    .bindTo(ctx, 'service-name')
    .then(function(service) {
      return service.singleArgMethod(ctx, 1);
    })
    .then(function(result) {
      assert.equal(result.method, 'SingleArgMethod');
      assert.equal(result.numInArgs, 1);
      assert.end();
    })
    .catch(assert.end);
});

test('Test that service.method() fails without a context - using callbacks',
  function(assert) {
  var client = new Client(mockProxy);
  var ctx = testContext();

  client.bindTo(ctx, 'service-name', function(err, service) {
    assert.error(err);

    service.tripleArgMethod(3, 'X', null, function(err, result) {
      assert.ok(err, 'should error');
      assert.notOk(result);
      assert.end();
    });
  });
});

test('Test that service.method() fails without a context - using promises',
  function(assert) {
  var client = new Client(mockProxy);
  var ctx = testContext();

  client.bindTo(ctx, 'service-name', function(err, service) {
    assert.error(err);

    service
      .singleArgMethod(1)
      .then(function(result) {
        assert.fail('should not succeed');
        assert.end();
      }, function(err) {
        assert.ok(err, 'should error');
        assert.end();
      })
      .catch(assert.end);
  });
});

function assertStrBoolNotCompatible(assert, err, result) {
  assert.ok(err, 'errors when receiving string instead of bool');
  assert.ok(err.message.indexOf('are not compatible') !== -1,
    'err is not compatible');
  assert.notOk(result, 'no result');
}

test('Test that service.method() fails when receiving bad outArgs - ' +
  'using callbacks', function(assert) {

  var client = new Client(mockProxy);
  var ctx = testContext();

  client.bindTo(ctx, 'service-name', function(err, service) {
    assert.error(err);

    service.lyingBoolMethod(ctx, function(err, result) {
      // LyingBoolMethod gives a string back, but it says it will be a bool.
      assertStrBoolNotCompatible(assert, err, result);
      assert.end();
    });
  });
});

test('Test that service.method() fails when receiving bad outArgs - ' +
  'using promises', function(assert) {
  var client = new Client(mockProxy);
  var ctx = testContext();

  client
    .bindTo(ctx, 'service-name')
    .catch(assert.end) // cannot fail here
    .then(function(service) {
      return service.lyingBoolMethod(ctx);
    })
    .then(function(result) {
      assert.end('Did not error when receiving string instead of bool');
    })
    .catch(function(err) {
      // LyingBoolMethod gives a string back, but it says it will be a bool.
      assertStrBoolNotCompatible(assert, err, null);
      assert.end();
    });
});

test('service.method() - callback error', function(assert) {
  var client = new Client(mockProxy);
  var ctx = testContext();

  client.bindTo(ctx, 'service-name', onservice);

  function onservice(err, service) {
    assert.error(err, 'should not error');

    service.tripleArgMethod(ctx, 3, 'X', onmethod);
  }

  function onmethod(err, result) {
    assert.ok(err, 'should error');
    assert.equal(err.message,
      'app:op: Client RPC call TripleArgMethod(3,X) had an incorrect ' +
      'number of arguments. Expected format: TripleArgMethod(a,b,c)');
    assert.notOk(result, 'should not have results');
    assert.end();
  }
});

test('service.method() - promise error', function(assert) {
  var client = new Client(mockProxy);
  var ctx = testContext();

  client
    .bindTo(ctx, 'service-name')
    .then(triggerError)
    .then(function(result) {
      assert.fail('should not succeed');
    }, function(err) {
      assert.ok(err, 'should error');
      assert.equal(err.message,
        'app:op: Client RPC call TripleArgMethod(3,X) had an incorrect ' +
        'number of arguments. Expected format: TripleArgMethod(a,b,c)'
      );
      assert.end();
    })
    .catch(assert.end);

  function triggerError(service) {
    // Calling with two args (after ctx)
    return service.tripleArgMethod(ctx, 3, 'X');
  }
});

test('var promise = client.signature(ctx, name) - promise', function(assert) {
  var client = new Client(mockProxy);
  var ctx = testContext();

  client.signature(ctx, 'service-name')
  .then(function(sigs) {
    assert.deepEqual(sigs, mockSignature);
    assert.end();
  }).catch(function(err) {
    assert.error(err);
    assert.end();
  });
});

test('client.signature(ctx, name, callback) - callback', function(assert) {
  var client = new Client(mockProxy);
  var ctx = testContext();

  client.signature(ctx, 'service-name', function(err, sigs) {
    assert.error(err);
    assert.deepEqual(sigs, mockSignature);
    assert.end();
  });

});

test('client.signature(name, callback) - no context', function(assert) {
  var client = new Client(mockProxy);

  client.signature('service-name', function(err, sigs) {
    assert.ok(err, 'should error');
    assert.notOk(sigs);
    assert.end();
  });
});

test('var promise = client.signature(name) - no context', function(assert) {
  var client = new Client(mockProxy);

  client.signature('service-name')
  .then(function(sigs) {
      assert.fail('should not succeed');
      assert.end();
  }).catch(function(err) {
    assert.ok(err, 'should error');
    assert.end();
  });
});
