// 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 Channel RPCs to Nacl plugin.
 */

var vom = require('../../../src/vom');
var TaskSequence = require('../../../src/lib/task-sequence');
var channelVdl =
  require('../../vdl/v.io/x/ref/services/wspr/internal/channel');
var browsprVdl =
  require('../../vdl/v.io/x/ref/services/wspr/internal/browspr');
var vlog = require('../../../src/lib/vlog');

module.exports = RpcChannel;

function uint8ArrayToArrayBuffer(arr) {
  return arr.buffer.slice(arr.byteOffset, arr.byteOffset + arr.length);
}

function RpcChannel(sendMessage) {
  if (!(this instanceof RpcChannel)) {
    return new RpcChannel(sendMessage);
  }
  this.sendMessage = sendMessage;
  this.lastSeq = 0;
  this.handlers = {};
  this.pendingCallbacks = {};
  this.decodeQueue = new TaskSequence();
}

RpcChannel.prototype.registerRpcHandler = function(type, func) {
  this.handlers[type] = func;
};

RpcChannel.prototype.performRpc = function(type, val, callback) {
  if (typeof val !== 'object') {
    throw new Error('val must be of type object, was ' + (typeof val));
  }

  var BrowsprMessage;
  switch(type) {
    case 'start':
      BrowsprMessage = browsprVdl.StartMessage;
      break;
    case 'auth:get-accounts':
      BrowsprMessage = browsprVdl.GetAccountsMessage;
      break;
    case 'auth:create-account':
      BrowsprMessage = browsprVdl.CreateAccountMessage;
      break;
    case 'auth:origin-has-account':
      BrowsprMessage = browsprVdl.OriginHasAccountMessage;
      break;
    case 'auth:associate-account':
      BrowsprMessage = browsprVdl.AssociateAccountMessage;
      break;
    case 'create-instance':
      BrowsprMessage = browsprVdl.CreateInstanceMessage;
      break;
    case 'cleanup':
      BrowsprMessage = browsprVdl.CleanupMessage;
      break;
    default:
      throw new Error('Unknown RPC type', type);
  }

  callback = callback || function(){};
  var seq = ++this.lastSeq;
  this.pendingCallbacks[seq] = callback;
  var request = new channelVdl.Request({
    type: type,
    seq: seq,
    body: new BrowsprMessage(val)
  });
  this._sendVomEncodedMessage(new channelVdl.Message({
    request: request
  }));
};

RpcChannel.prototype._sendVomEncodedMessage = function(msg) {
  var writer = new vom.ByteArrayMessageWriter();
  var enc = new vom.Encoder(writer);
  enc.encode(msg);
  var encodedBytes = writer.getBytes();
  this._postMessage(uint8ArrayToArrayBuffer(encodedBytes));
};

RpcChannel.prototype._handleRequest = function(req) {
  var type = req.type;
  var handler = this.handlers[type];
  if (handler === undefined) {
    throw new Error('Undefined handler for type \'' + type + '\'');
  }
  var result;
  var err;
  try {
    result = handler(req.body);
  } catch (e) {
    err = e.message;
    // TODO(bprosnitz) Nil is not handled yet in VOM2.
    // Remove this when it is implemented.
    result = 'ResultMessageToBeRemovedWhenVOM2IsComplete';
  }
  var response = new channelVdl.Response({
    reqSeq: req.Seq,
    err: err || '',
    body: result
  });
  this._sendVomEncodedMessage(new channelVdl.Message({
    response: response
  }));
};

RpcChannel.prototype._handleResponse = function(resp) {
  var seq = resp.reqSeq;
  var cb = this.pendingCallbacks[seq];
  delete this.pendingCallbacks[seq];
  if (cb === undefined) {
    throw new Error('Received response with no matching sequence number '+
      JSON.stringify(resp));
  }
  if (resp.err !== '') {
    return cb(new Error(resp.err));
  }
  // TODO(nlacasse,bpronitz): Is it OK to just call "val" on the body like this?
  var body = resp.body && resp.body.val;
  cb(null, body);
};

RpcChannel.prototype._handleMessageTask = function(msg) {
  var msgBytes = new Uint8Array(msg);
  var reader = new vom.ByteArrayMessageReader(msgBytes);
  var dec = new vom.Decoder(reader);
  var channel = this;
  return dec.decode().then(function(jsMsg) {
    if (jsMsg._type.name === channelVdl.Message.name) {
      throw new Error('Message does not have correct Message type: ' +
                      JSON.stringify(jsMsg));
    } else if (jsMsg.request) {
      return channel._handleRequest(jsMsg.request);
    } else if (jsMsg.response) {
      return channel._handleResponse(jsMsg.response);
    } else {
      var err = new Error('Message has Message type, but no "request" or ' +
                          '"response" fields: ' + JSON.stringify(jsMsg));
      vlog.logger.error(err + ': ' + err.stack);
    }
  }, function(err) {
    vlog.logger.error(err + ': ' + err.stack);
  });
};
RpcChannel.prototype.handleMessage = function(msg) {
  // We add this to the task queue to make sure that the decode callback for
  // all the messages are peformed in order.
  this.decodeQueue.addTask(this._handleMessageTask.bind(this, msg));
};

RpcChannel.prototype._postMessage = function(msg) {
  this.sendMessage({
    type: 'browsprRpc',
    instanceId: -1,
    origin: '',
    body: msg,
  });
};
