// 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 inherits = require('inherits');
var vanadium = require('vanadium');

module.exports = {
  addNameProperties: addNameProperties,
  getChildNames: getChildNames,
  prefixRangeLimit: prefixRangeLimit,
  InvalidNameError: InvalidNameError,
  stringToUTF8Bytes: stringToUTF8Bytes
};

/**
 * Creates the 'name' and 'fullName' properties on an object.
 * @private
 */
function addNameProperties(self, parentFullName, relativeName) {
  if (relativeName.indexOf('/') >= 0) {
    throw new InvalidNameError(relativeName);
  }

  var fullName = vanadium.naming.join(parentFullName, relativeName);

  /**
   * @property name
   * @type {string}
   */
  Object.defineProperty(self, 'name', {
    value: relativeName,
    writable: false,
    enumerable: true
  });

  /**
   * @property name
   * @type {string}
   */
  Object.defineProperty(self, 'fullName', {
    value: fullName,
    writable: false,
    enumerable: true
  });
}

function InvalidNameError(name) {
  Error.call(this);
  this.message = 'Invalid name "' + name + '". ' +
    ' Use vanadium.naming.encodeAsNamePart() to escape.';
}
inherits(InvalidNameError, Error);

/**
 * getChildNames returns all names that are children of the parentFullName.
 * @private
 */
function getChildNames(ctx, parentFullName, cb) {
  var rt = vanadium.runtimeForContext(ctx);
  var namespace = rt.namespace();
  var childNames = [];

  var globPattern = vanadium.naming.join(parentFullName, '*');

  var stream = namespace.glob(ctx, globPattern, function(err) {
    if (err) {
      return cb(err);
    }

    cb(null, childNames);
  }).stream;

  stream.on('data', function(globResult) {
    var fullName = globResult.name;
    var name = vanadium.naming.basename(fullName);
    childNames.push(name);
  });

  stream.on('error', function(err) {
    console.error('Stream error: ' + JSON.stringify(err));
  });
}

/**
 * PrefixRangeLimit returns the limit of the row range for the given prefix.
 * @private
 * @param {Uint8Array} bytes Integer ArrayBuffer to modify.
 */
function prefixRangeLimit(bytes) {
  // For a given Uint8Array,
  // The code below effectively adds 1 to it, then chops off any
  // trailing \x00 bytes.
  // If the input string consists entirely of \xff bytes, we would empty out the
  // buffer
  while (bytes.length > 0) {
    var last = bytes.length - 1;
    if (bytes[last] === 255) {
      bytes = bytes.slice(0, last); // remove trailing \x00
    } else {
      bytes[last] += 1; // add 1
      return; // no carry
    }
  }
}

/**
 * stringToUTF8Bytes converts a JavaScript string to a array of bytes
 * representing the string in UTF8 format.
 * @private
 * @param {string} str String to convert to UTF8 bytes.
 * @return {Uint8Array} UTF8 bytes.
 */
function stringToUTF8Bytes(str) {
  var utf8String = unescape(encodeURIComponent(str)); //jshint ignore:line
  var bytes = new Uint8Array(utf8String.length);

  for (var i = 0; i < utf8String.length; i++) {
    bytes[i] = utf8String.charCodeAt(i);
  }

  return bytes;
}