// 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 vdl = require('../gen-vdl/v.io/x/ref/services/wspr/internal/namespace');
var time = require('../gen-vdl/v.io/v23/vdlroot/time');
var emitStreamError = require('../lib/emit-stream-error');
var Readable = require('stream').Readable;
var inherits = require('util').inherits;

module.exports = Namespace;

/**
 * @summary
 * Namespace defines the APIs for resolving, globbing and managing names.
 *
 * @description
 * <p>Private Constructor. Use
 * [runtime.namespace]{@link module:vanadium~Runtime#namespace} to get an
 * instance.</p>
 *
 * @constructor
 * @inner
 * @memberof module:vanadium.naming
 */
function Namespace(client, rootCtx) {
  this._namespace = client.bindWithSignature(
    '__namespace', [vdl.Namespace.prototype._serviceDescription]);
  this._rootCtx = rootCtx;
}

function GlobStream(orig) {
  Readable.call(this, {objectMode: true});
  this._orig = orig;

  var stream = this;
  orig.on('end', function() {
    if (!stream._flow(true)) {
      orig.on('writable', stream._flow.bind(stream, true));
    }
  });
  orig.on('readable', stream._flow.bind(stream, false));

  stream._flow(false);
}

inherits(GlobStream, Readable);

GlobStream.prototype._flow = function(drain) {
  // We split the GlobReply union type and send GlobErrors through the
  // stream's error channel and valid MountPoints through the data channel.
  var chunk;
  while((chunk = this._orig.read()) !== null) {
    if (chunk.entry) {
      if (!this.push(chunk.entry)) {
        return false;
      }
    } else if (chunk.error) {
      emitStreamError(this, chunk.error);
    }
  }
  if (drain) {
    this.push(null);
  }
  return true;
};

GlobStream.prototype._read = function() {
  // We don't need to do anything, we're always trying to read.
};

/**
 * Glob streams all names matching pattern. If recursive is true, it also
 * returns all names below the matching ones.
 * @param {module:vanadium.context.Context} ctx The rpc context.
 * @param {string} pattern Glob pattern to match
 * @param {function} cb(error) Optional callback
 * @return {Promise} A promise with an stream object hanging from it.
 */
Namespace.prototype.glob = function(ctx, pattern, cb) {
  var promise = this._namespace.glob(ctx, pattern, cb);

  // We get back a single stream of errors and entries,
  // we now split them into a separate stream of errors and
  // data via a transform stream.
  var newPromise = Promise.resolve(promise);
  newPromise.stream = new GlobStream(promise.stream);
  return newPromise;
};

/**
 * Mount the server object address under the object name, expiring after
 * @param {module:vanadium.context.Context} ctx The rpc context.
 * @param {string} name Object name
 * @param {string} server Server object address
 * @param {number} ttl Expiry time for the mount in milliseconds. ttl of zero
 * implies never expire.
 * @param {boolean} [replaceMount] Whether the previous mount should
 * be replaced by the new server object address. False by default.
 * @param {function} cb(error) Optional callback
 * @return {Promise} A promise to be resolved when mount is complete or rejected
 * when there is an error
 */
Namespace.prototype.mount = function(ctx, name, server, ttl, replaceMount,
                                     cb) {
  ttl = ttl || 0; // Default is 0
  var duration = new time.Duration({
    seconds: Math.floor(ttl / 1000),
    nanos: (ttl % 1000) * 1000000
  });
  replaceMount = !!replaceMount; // Cast to bool
  return this._namespace.mount(ctx, name, server, duration, replaceMount, cb);
};

/**
 * Unmount the server object address from the object name, or if server is empty
 * unmount all server object address from the object name.
 * @param {module:vanadium.context.Context} ctx The rpc context.
 * @param {string} name Object name
 * @param {string} server Server object address
 * @param {function} cb(error) Optional callback
 * @return {Promise} A promise to be resolved when unmount is complete or
 * rejected when there is an error
 */
Namespace.prototype.unmount = function(ctx, name, server, cb) {
  return this._namespace.unmount(ctx, name, server, cb);
};

/**
 * Resolve the object name into its mounted servers.
 * @param {module:vanadium.context.Context} ctx The rpc context
 * @param {string} name Object name
 * @param {function} cb(error, string[]) Optional callback
 * @return {Promise<string[]>} A promise to be resolved a string array of server
 * object object addresses or rejected when there is an error
 */
Namespace.prototype.resolve = function(ctx, name, cb) {
  return this._namespace.resolve(ctx, name, cb);
};

/**
 * ResolveToMountTable resolves the object name into the mounttables
 * directly responsible for the name.
 * @param {module:vanadium.context.Context} ctx The rpc context.
 * @param {string} name Object name
 * @param {function} cb(error, string[]) Optional callback
 * @return {Promise<string[]>} A promise to be resolved a string array of
 * mounttable object addresses or rejected when there is an error
 */
Namespace.prototype.resolveToMounttable = function(ctx, name, cb) {
  return this._namespace.resolveToMountTable(ctx, name, cb);
};

/*
 * FlushCacheEntry flushes resolution information cached for the name.
 * @param {string} name Object name
 * @param {function} cb(error, boolean) Optional callback
 * @return {Promise<boolean>} A promise to be resolved a boolean indicating if
 * anything was flushed or rejected when there is an error
 */
Namespace.prototype.flushCacheEntry = function(name, cb) {
  return this._namespace.flushCacheEntry(this._rootCtx, name, cb);
};

/*
 * Disables the resolution cache when set to true and enables if false.
 * @param {boolean} disable Whether to disable or enable cache.
 * @param {function} cb(error) Optional callback
 * @return {Promise} A promise to be resolved when disableCache is complete or
 * rejected when there is an error
 */
Namespace.prototype.disableCache = function(disable, cb) {
  disable = !!disable; // Cast to bool
  return this._namespace.disableCache(this._rootCtx, disable, cb);
};

/**
 * Returns the currently configured roots. An empty array is returned if no
 * roots are configured.
 * @param {function} cb(error, string[]) Optional callback
 * @return {Promise<string[]>} A promise to be resolved with an array of root
 * object names when getRoots is complete or rejected when there is an error
 */
Namespace.prototype.roots = function(cb) {
  return this._namespace.roots(this._rootCtx, cb);
};

/**
 * Sets the roots that the local Namespace is relative to.
 * All relative names passed to the methods above will be interpreted as
 * relative to these roots.
 * The roots will be tried in the order that they are specified in the parameter
 * list for setRoots.
 * @param {...string} roots object names for the roots
 * @param {function} cb(error) Optional callback
 * @return {Promise} A promise to be resolved when setRoots is complete or
 * rejected when there is an error
 */
Namespace.prototype.setRoots = function(roots, cb) {
  if (!Array.isArray(roots)) {
    roots = Array.prototype.slice.call(arguments);
    if (typeof roots[roots.length - 1] === 'function') {
      cb = roots.pop();
    } else {
      cb = undefined;
    }
  }
  return this._namespace.setRoots(this._rootCtx, roots, cb);
};

/**
 * Sets the Permissions on a namespace.
 * If version is specified and is different from the current version on the
 * Permissions, an error will be returned.
 * Note that setPermissions will completely replace the Permissions on the
 * name.  If you want to update only a part of the Permissions, you must first
 * call getPermissions, modify the returned Permissions, and then call
 * setPermissions with the modified Permissions. You should use the version
 * parameter in this case to ensure that the Permissions has not been modified
 * in between read and write.
 * @param {module:vanadium.context.Context} ctx The rpc context.
 * @param {string} name name to set the Permissions of
 * @param {Map} perms Permissions to set on the name
 * @param {string} version Optional version of the Permissions
 * @param {function} cb(error) Optional callback
 * @return {Promise} A promise to be resolved when setPermissions is complete
 * or rejected when there is an error.
 */
Namespace.prototype.setPermissions = function(ctx, name, perms, version, cb) {
  // TODO(nlacasse): Should we provide an updatePermissions helper method that
  // wraps getPermissions/setPermissions? It's not clear exactly how it would
  // work (what to overwrite, what to append), but we should consider it.
  if (typeof version === 'function') {
    cb = version;
    version = '';
  }
  if (typeof version === 'undefined') {
    version = '';
  }

  return this._namespace.setPermissions(ctx, name, perms, version, cb);
};

/**
 * Gets the Permissions on a namespace.
 * @param {module:vanadium.context.Context} ctx The rpc context.
 * @param {string} name name to get the Permissions of
 * @param {function} cb(error, perms, version) Optional callback
 * @return {Promise} A promise to be resolved when getPermissions is complete
 * or rejected when there is an error.
 */
Namespace.prototype.getPermissions = function(ctx, name, cb) {
  return this._namespace.getPermissions(ctx, name, cb);
};

/**
 * Deletes a name from the namespace, and possibly all names in subtree.
 * @param {module:vanadium.context.Context} ctx The rpc context.
 * @param {string} name name to delete
 * @param {boolean} deleteSubtree whether to delete all decendent names in
 * subtree.  If deleteSubtree is false and the name has decendents, then the
 * deletion will fail.
 * @param {function} cb(error) Optional callback
 * @return {Promise} A promise to be resolved when delete is complete or
 * rejected when there is an error.
 */
Namespace.prototype.delete = function(ctx, name, deleteSubtree, cb) {
  return this._namespace.delete(ctx, name, deleteSubtree, cb);
};
