// 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 Registry for caveats. Provides a mapping between caveat
 * UUIDs and validations methods.
 * @private
 */

var vdl = require('../vdl');
var vom = require('../vom');
var byteUtil = require('../vdl/byte-util');
var standardCaveats = require('./standard-caveat-validators');
var vdlSecurity = require('../gen-vdl/v.io/v23/security');
var unwrapArg = require('../lib/unwrap-arg');
var InspectableFunction = require('../lib/inspectable-function');
var asyncCall = require('../lib/async-call');

module.exports = CaveatValidatorRegistry;

/**
 * @summary CaveatValidatorRegistry is a registry for caveats.
 * @description
 * It enables registration of caveat validation functions and provides
 * provides functionality to perform validation given UUIDs. This constructor
 * should not be invoked directly, but rather the
 * [singleton]{@link Runtime.caveatRegistry} on {@link Runtime} should be used.
 * @constructor
 * @inner
 * @memberof module:vanadium.security
 */
function CaveatValidatorRegistry() {
  this.validators = new Map();

  standardCaveats.registerDefaultCaveats(this);
}

/**
 * _makeKey generates a key for the given Uint8Array.
 * This is needed because ES6 map does === comparison and equivalent arrays
 * can be different under ===.
 * @private
 */
CaveatValidatorRegistry.prototype._makeKey = function(bytes) {
  return byteUtil.bytes2Hex(bytes);
};

/**
 * @callback CaveatValidationFunction
 * A function to validate caveats on {@link Blessings}
 * @param {module:vanadium.context.Context} ctx The context of the call.
 * @param {module:vanadium.security~SecurityCall} secCall The security call
 * to validate.
 * @memberof module:vanadium.security
 * @param {*} param Validation-function specific parameter.
 * @throws {Error} If validation fails.
 */

/**
 * Register a caveat validation function.
 * @param {module:vanadium.security.CaveatDescriptor} cavDesc The caveat
 * description.
 * @param {module:vanadium.security.CaveatValidationFunction} validateFn
 * The validation function.
 */
CaveatValidatorRegistry.prototype.register = function(cavDesc, validateFn) {
  this.validators.set(
    this._makeKey(cavDesc.id),
    new CaveatValidator(cavDesc, validateFn)
  );
};

/**
 * Perform validation on a caveat.
 * @param {module:vanadium.context.Context} ctx The context.
 * @param {module:vanadium.security.SecurityCall} secCall The security call.
 * @param {*} caveat The caveat to validate.
 * @param {Function} [cb] Callback after validation is complete.
 * See security/types.vdl
 * @throws {Error} If validation fails.
 * @private
 */
CaveatValidatorRegistry.prototype.validate =
  function(ctx, call, caveat, cb) {
  var validator = this.validators.get(this._makeKey(caveat.id));
  if (validator === undefined) {
    return cb(new vdlSecurity.CaveatNotRegisteredError(ctx,
      'Unknown caveat id: ' + this._makeKey(caveat.id)));
  }
  return vom.decode(caveat.paramVom, false, null, function(err, val) {
    if (err) {
      return cb(err);
    }
    return validator.validate(ctx, call, val, cb);
  });
};

/**
 * CaveatValidator is a helper object representing a specific caveat
 * description and function pair.
 * @private
 */
function CaveatValidator(cavDesc, validateFn) {
  this.cavDesc = cavDesc;
  this.validateFn = validateFn;
}

/**
 * @private
 */
CaveatValidator.prototype.validate = function(ctx, call, paramForValidator,
                                              cb) {
  var paramType = this.cavDesc.paramType;
  var canonParam = vdl.canonicalize.reduce(paramForValidator, paramType);
  var unwrappedParam = unwrapArg(canonParam, paramType);

  var inspectableFn = new InspectableFunction(this.validateFn);
  asyncCall(ctx, null, inspectableFn, [], [ctx, call, unwrappedParam], cb);
};
