// 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.

/**
 * @fileoverview Defines an invoker to invoke service methods.
 * @private
 */

module.exports = Invoker;

var createSignature = require('../vdl/create-signature');
var isPublicMethod = require('../lib/service-reflection').isPublicMethod;
var verror = require('../gen-vdl/v.io/v23/verror');
var capitalize = require('../vdl/util').capitalize;
var isCapitalized = require('../vdl/util').isCapitalized;
var format = require('format');
var context = require('../context');
var asyncCall = require('../lib/async-call');
var InspectableFunction = require('../lib/inspectable-function');

// Method signatures for internal methods that are not present in actual
// signatures.
// These signatures are meant to simplify the implementation of invoke
// and may be partial.
var internalMethodSignatures = {
  __glob: {
    name: '__glob',
    outArgs: []
  },
  __globChildren: {
    name: '__globChildren',
    outArgs: []
  }
};

/**
  * Create an invoker.
  * @param {Service} service Service object.
  * @constructor
  * @private
  */
function Invoker(service) {
  if (!(this instanceof Invoker)) {
    return new Invoker(service);
  }

  var invoker = this;

  invoker._service = service;
  invoker._signature = createSignature(service, service._serviceDescription);
  invoker._methods = {};

  // See comment in src/vdl/reflect-signature.js for..in loop
  for (var key in service) { // jshint ignore:line
    if (!isPublicMethod(key, service)) {
      continue;
    }

    if (isCapitalized(key)) {
      throw new Error('Can\'t export capitalized method ' + key);
    }

    var capitalizedMethodName = capitalize(key);
    var method = service[key];

    var inspectableFn = new InspectableFunction(method);
    // Check whether the number of args reported by javascript (method.length)
    // and the number of args retrieved from fn.toString() are the same.
    // This usually differs if the method is a native method.
    if (inspectableFn.names.length !== method.length) {
      throw new Error('Function "' + key + '" can not be inspected. ' +
        'This is usually because it is a native method or bind is used.');
    }

    invoker._methods[capitalizedMethodName] = {
      name: capitalizedMethodName,
      fn: inspectableFn
    };
  }


  var fn;
  if (typeof service.__glob === 'function') {
    fn = new InspectableFunction(service.__glob);
    if (fn.filteredNames.length !== 1 ||
        fn.names.indexOf('$stream') === -1) {
      // TODO(bjornick): Throw a verror of appropriate type.
      throw new Error(
        '__glob needs to take in a string and be streaming');
    }

    this._methods.__glob = {
      name: '__glob',
      fn: fn
    };
  }

  if (typeof service.__globChildren === 'function') {
    fn = new InspectableFunction(service.__globChildren);
    if (fn.filteredNames.length !== 0 ||
        fn.names.indexOf('$stream') === -1 ) {
      // TODO(bjornick): Throw a verror of appropriate type.
      throw new Error(
        '__globChildren needs to take in no args and be streaming');
    }

    this._methods.__globChildren = {
      name: '__globChildren',
      fn: fn
    };
  }
}

Invoker.prototype.hasGlobber = function() {
  return this.hasMethod('__glob') || this.hasMethod('__globChildren');
};

/**
 * Find a method signature corresponding to the named method.
 *
 * @param {String} methodName - The name of the method
 * @return {MethodSignature} The signature of the named method, or null.
 * @private
 */
Invoker.prototype._findMethodSignature = function(methodName) {
  for (var i = 0; i < this._signature.length; i++) {
    var sig = this._signature[i];
    if (sig.methods) {
      for (var m = 0; m < sig.methods.length; m++) {
        var method = sig.methods[m];
        if (method.name === methodName) {
          return method;
        }
      }
    }
  }
  return null;
};

/**
 * Invoker.prototype.invoke - Invoke a method
 *
 * @param  {String} name - The upper camel case name of the method to invoke.
 * @param  {Array} args - A list of arguments to call the method with, may
 * differ because of injections e.g. function x(a,$stream,b) => [0, 2].
 * @param  {Object} injections - A map of injections, should always
 * contain `context`, could also contain `stream`
 * e.g. function(ctx, x, $stream, b)
 * @param  {Invoker~invokeCallback} cb - The callback fired after completion.
 */
Invoker.prototype.invoke = function(name, args, injections, cb) {
  // TODO(jasoncampbell): Maybe throw if there are unkown injections

  var message;
  var err;

  var invoker = this;
  var method = invoker._methods[name];
  var errorContext = injections.context || new context.Context();
  if (!method) {
    message = format('Method "%s"', name);
    err = new verror.NoExistError(errorContext, message);

    cb(err);
    return;
  }
  var methodSig = this._findMethodSignature(name) ||
    internalMethodSignatures[name];
  if (!methodSig) {
    cb(verror.InternalError(errorContext,
                            'Missing method signature for method ' + name));
  }

  if (!injections.context) {
    message = 'Can not call invoker.invoke(...) without a context injection';
    err = verror.InternalError(errorContext, message);
    cb(err);
    return;
  }

  var arity = method.fn.arity();

  // Check argument arity against the method's declared arity
  if (args.length !== arity) {
    var template = 'Expected %d arguments but got "%s"';

    message = format(template, arity, args.join(', '));
    err = new verror.BadArgError(errorContext, message);
    cb(err);
    return;
  }

  // Clone the array so we can simply manipulate and apply later
  var clonedArgs = args.slice(0);

  // call and context go in front
  clonedArgs.unshift(injections.call);
  clonedArgs.unshift(injections.context);

  // splice in stream
  if (injections.stream) {
    var start = method.fn.position('$stream');
    var deleteCount = 0;

    clonedArgs.splice(start, deleteCount, injections.stream);
  }

  asyncCall(injections.context, invoker._service, method.fn,
    methodSig.outArgs.length, clonedArgs, cb);
};

/**
 * This callback is fired on completion of invoker.invoke.
 * @callback Invoker~invokeCallback
 * @param {Error} err
 * @param {results} results
 */

/**
 * Return the signature of the service.
 * @return {Object} The signature
 */
Invoker.prototype.signature = function() {
  return this._signature;
};


/**
 * returns whether the function <name> is invokable.
 * @param {string} name the name of the function
 * @return {boolean} whether the function is invokable.
 */
Invoker.prototype.hasMethod = function(name) {
  return !!this._methods[name];
};
