// 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 Vanadium Runtime
 * @private
 */
var EE = require('eventemitter2').EventEmitter2;
var isBrowser = require('is-browser');
var Deferred = require('../lib/deferred');
var inherits = require('inherits');
var Server = require('../rpc/server');
var ServerRouter = require('../rpc/server-router');
var GranterRouter = require('../rpc/granter-router');
var Client = require('../rpc/client');
var Namespace = require('../naming/namespace');
var CaveatValidatorRegistry = require('../security/caveat-validator-registry');
var Principal = require('../security/principal');
var vlog = require('../lib/vlog');
var context = require('../context');
var SharedContextKeys = require('./shared-context-keys');
var vtrace = require('../vtrace');
var Controller =
  require('../gen-vdl/v.io/x/ref/services/wspr/internal/app').Controller;

module.exports = {
  init: init
};

/*
 * Initialize a Vanadium Runtime.
 * Runtime exposes entry points to create servers, client, blessing and other
 * Vanadium functionality.
 * @private
 */
function init(options, cb) {
  var rt = new Runtime(options);
  var promise = Promise.resolve(rt);

  if (isBrowser) {
    // In the browser, we must create the app instance in browspr.  We send
    // along the namespaceRoots and proxy, if they have been provided.  If they
    // are empty, the defaults from the extension options page will be used.
    var settings = {
      namespaceRoots: options.namespaceRoots || [],
      proxy: options.proxy || ''
    };

    promise = promise.then(function(rt) {
      var def = new Deferred();
      rt._getProxyConnection().createInstance(settings, function(err) {
        if (err) {
          return def.reject(err);
        }
        def.resolve(rt);
      });
      return def.promise;
    });
  }

  promise = promise.then(function() {
    return rt.principal._loadDefaultBlessings();
  }).then(function() {
    return rt;
  });

  promise.then(function(rt) {
    cb(null, rt);
  }, function(err) {
    cb(err);
  });
  return promise;
}

/**
 * @summary
 * Runtime exposes entry points to create servers, client, namespace client and
 * other Vanadium functionality.
 * @Description
 * <p>This constructor should not be used directly, instead use
 * [vanadium.init]{@link module:vanadium.init}</p>
 *
 * <p>Runtime is also an EventEmitter:</p>
 * <p>
 *    Event: 'crash':
 *    Emitted when the runtime crashes in an unexpected way. Recovery from
 *    crash event requires restarting the application.
 * </p>
 * @property {string} accountName The accountName that the user associated to
 * this runtime.
 * @property {module:vanadium.security~Principal} principal The principal
 * associated with this runtime.  All operations that come from this
 * runtime, including operations that come from
 * [Servers]{@link module:vanadium.rpc~Server} and
 * [Clients]{@link module:vanadium.rpc~Client}, will use this principal.
 * @property {module:vanadium.security~CaveatValidatorRegistry} caveatRegistry
 * Used to register custom first party caveat validators.
 * @inner
 * @memberof module:vanadium
 * @constructor
 */
function Runtime(options) {
  if (!(this instanceof Runtime)) {
    return new Runtime(options);
  }

  EE.call(this);

  this.accountName = options.accountName;
  this._wspr = options.wspr;
  var client = this.newClient();
  this._controller = client.bindWithSignature(
    '__controller', [Controller.prototype._serviceDescription]);
  this.principal = new Principal(this.getContext(), this._controller);
  this._name = options.appName;
  this._language = options.language;
  this.caveatRegistry = new CaveatValidatorRegistry();
}

inherits(Runtime, EE);

/**
 * Closes the runtime, freeing all the related resources and stopping and
 * unpublishing all the servers created in the runtime.
 *
 * @param {function} [cb] Gets called once the runtime is closed.
 * @returns {Promise} Promise that will be resolved or rejected when runtime is
 * closed.
 */
Runtime.prototype.close = function(cb) {
  if (this._crashed) {
    // NaCl plugin crashed. Shutting down will not work.
    return process.nextTick(function() {
      cb(new Error('Runtime crashed, can not shutdown gracefully.'));
    });
  }

  var router = this._getRouter();
  var proxy = this._getProxyConnection();
  return router.cleanup().then(function() {
      return proxy.close(cb);
  });
};

/**
 * Creates a new [Server]{@link module:vanadium.rpc~Server} instance.<br>
 * Server allows one to create, publish and stop Vanadium services.
 * @return {module:vanadium.rpc~Server} A server instance.
 */
Runtime.prototype.newServer = function() {
  return new Server(this._getRouter());
};

/**
 * Creates a new [Client]{@link module:vanadium.rpc~Client} instance.<br>
 * Client allows one to bind to Vanadium names and call methods on them.
 * @return {module:vanadium.rpc~Client} A Client instance.
 */
Runtime.prototype.newClient = function() {
  return new Client(this._getProxyConnection());
};

/**
 * Returns the root runtime [context]{@link module:vanadium.context.Context}<br>
 * Context objects provide a number of features such as
 * ability to provide configuration for requests such as timeout durations,
 * tracing across requests for debugging, etc...<br>
 * In order to provide these facilities context objects are required as the
 * first parameter for client calls and also for requests that are incoming
 * to servers.
 * @return {module:vanadium.context.Context} The root runtime context.
 */
Runtime.prototype.getContext = function() {
  if (this._rootCtx) {
    return this._rootCtx;
  }
  var ctx = new context.Context();
  ctx = ctx.withValue(SharedContextKeys.COMPONENT_NAME, this._name);
  if (this._language) {
    ctx = ctx.withValue(SharedContextKeys.LANG_KEY, this._language);
  }
  ctx = ctx.withValue(SharedContextKeys.RUNTIME, this);
  ctx = vtrace.withNewStore(ctx);
  ctx = vtrace.withNewTrace(ctx);
  this._rootCtx = ctx;
  return ctx;
};

/**
 * <p>Returns a [namespace]{@link module:vanadium.naming~Namespace} client.</p>
 * <p>Namespace client enables interactions with the Vanadium namespace such as
 * globbing, mounting, setting permissions and other name related operations.
 * </p>
 * @return {module:vanadium.naming~Namespace} A namespace client instance.
 */
Runtime.prototype.namespace = function() {
  this._ns = this._ns || new Namespace(this.newClient(),
    this.getContext());
  return this._ns;
};

/**
 * Get or creates a new proxy connection
 * @return {ProxyConnection} A proxy connection
 * @private
 */
Runtime.prototype._getProxyConnection = function() {
  if (this._proxyConnection) {
    return this._proxyConnection;
  }

  var ProxyConnection;
  if (this._wspr) {
    vlog.logger.info('Using WSPR at: %s', this._wspr);
    ProxyConnection = require('../proxy/websocket');
    this._proxyConnection = new ProxyConnection(this._wspr);
  } else {
    vlog.logger.info('Using the Vanadium Extension\'s NaCl WSPR');
    ProxyConnection = require('../proxy/nacl');
    this._proxyConnection = new ProxyConnection();
  }

  // relay crash event from proxy
  var self = this;
  this._proxyConnection.on('crash', function(e) {
    self._crashed = true;
    self.emit('crash', e);
  });

  return this._proxyConnection;
};

/**
 * Get or creates a router
 * @return {ServerRouter} A router
 * @private
 */
Runtime.prototype._getRouter = function() {
  if (!this._router) {
    this._router = new ServerRouter(
      this._getProxyConnection(),
      this._name,
      this.getContext(),
      this._controller,
      this.caveatRegistry);
  }
  return this._router;
};

/**
 * Get or creates a granter router
 * @return {GranterRouter} A granter router
 * @private
 */
Runtime.prototype._getGranterRouter = function() {
  if (!this._granterRouter) {
    this._granterRouter = new GranterRouter(
      this._getProxyConnection(),
      this.getContext());
  }
  return this._granterRouter;
};
