// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// -----------------------------------------------------------------------------
// NOTE: If you change this file you need to touch renderer_resources.grd to
// have your change take effect.
// -----------------------------------------------------------------------------

//==============================================================================
// This file contains a class that implements a subset of JSON Schema.
// See: http://www.json.com/json-schema-proposal/ for more details.
//
// The following features of JSON Schema are not implemented:
// - requires
// - unique
// - disallow
// - union types (but replaced with 'choices')
//
// The following properties are not applicable to the interface exposed by
// this class:
// - options
// - readonly
// - title
// - description
// - format
// - default
// - transient
// - hidden
//
// There are also these departures from the JSON Schema proposal:
// - function and undefined types are supported
// - null counts as 'unspecified' for optional values
// - added the 'choices' property, to allow specifying a list of possible types
//   for a value
// - by default an "object" typed schema does not allow additional properties.
//   if present, "additionalProperties" is to be a schema against which all
//   additional properties will be validated.
//==============================================================================

var loadTypeSchema = require('utils').loadTypeSchema;
var CHECK = requireNative('logging').CHECK;

function isInstanceOfClass(instance, className) {
  while ((instance = instance.__proto__)) {
    if (instance.constructor.name == className)
      return true;
  }
  return false;
}

function isOptionalValue(value) {
  return typeof(value) === 'undefined' || value === null;
}

function enumToString(enumValue) {
  if (enumValue.name === undefined)
    return enumValue;

  return enumValue.name;
}

/**
 * Validates an instance against a schema and accumulates errors. Usage:
 *
 * var validator = new JSONSchemaValidator();
 * validator.validate(inst, schema);
 * if (validator.errors.length == 0)
 *   console.log("Valid!");
 * else
 *   console.log(validator.errors);
 *
 * The errors property contains a list of objects. Each object has two
 * properties: "path" and "message". The "path" property contains the path to
 * the key that had the problem, and the "message" property contains a sentence
 * describing the error.
 */
function JSONSchemaValidator() {
  this.errors = [];
  this.types = [];
}

JSONSchemaValidator.messages = {
  invalidEnum: "Value must be one of: [*].",
  propertyRequired: "Property is required.",
  unexpectedProperty: "Unexpected property.",
  arrayMinItems: "Array must have at least * items.",
  arrayMaxItems: "Array must not have more than * items.",
  itemRequired: "Item is required.",
  stringMinLength: "String must be at least * characters long.",
  stringMaxLength: "String must not be more than * characters long.",
  stringPattern: "String must match the pattern: *.",
  numberFiniteNotNan: "Value must not be *.",
  numberMinValue: "Value must not be less than *.",
  numberMaxValue: "Value must not be greater than *.",
  numberIntValue: "Value must fit in a 32-bit signed integer.",
  numberMaxDecimal: "Value must not have more than * decimal places.",
  invalidType: "Expected '*' but got '*'.",
  invalidTypeIntegerNumber:
      "Expected 'integer' but got 'number', consider using Math.round().",
  invalidChoice: "Value does not match any valid type choices.",
  invalidPropertyType: "Missing property type.",
  schemaRequired: "Schema value required.",
  unknownSchemaReference: "Unknown schema reference: *.",
  notInstance: "Object must be an instance of *."
};

/**
 * Builds an error message. Key is the property in the |errors| object, and
 * |opt_replacements| is an array of values to replace "*" characters with.
 */
JSONSchemaValidator.formatError = function(key, opt_replacements) {
  var message = this.messages[key];
  if (opt_replacements) {
    for (var i = 0; i < opt_replacements.length; i++) {
      message = message.replace("*", opt_replacements[i]);
    }
  }
  return message;
};

/**
 * Classifies a value as one of the JSON schema primitive types. Note that we
 * don't explicitly disallow 'function', because we want to allow functions in
 * the input values.
 */
JSONSchemaValidator.getType = function(value) {
  var s = typeof value;

  if (s == "object") {
    if (value === null) {
      return "null";
    } else if (Object.prototype.toString.call(value) == "[object Array]") {
      return "array";
    } else if (typeof(ArrayBuffer) != "undefined" &&
               value.constructor == ArrayBuffer) {
      return "binary";
    }
  } else if (s == "number") {
    if (value % 1 == 0) {
      return "integer";
    }
  }

  return s;
};

/**
 * Add types that may be referenced by validated schemas that reference them
 * with "$ref": <typeId>. Each type must be a valid schema and define an
 * "id" property.
 */
JSONSchemaValidator.prototype.addTypes = function(typeOrTypeList) {
  function addType(validator, type) {
    if (!type.id)
      throw new Error("Attempt to addType with missing 'id' property");
    validator.types[type.id] = type;
  }

  if (typeOrTypeList instanceof Array) {
    for (var i = 0; i < typeOrTypeList.length; i++) {
      addType(this, typeOrTypeList[i]);
    }
  } else {
    addType(this, typeOrTypeList);
  }
}

/**
 * Returns a list of strings of the types that this schema accepts.
 */
JSONSchemaValidator.prototype.getAllTypesForSchema = function(schema) {
  var schemaTypes = [];
  if (schema.type)
    $Array.push(schemaTypes, schema.type);
  if (schema.choices) {
    for (var i = 0; i < schema.choices.length; i++) {
      var choiceTypes = this.getAllTypesForSchema(schema.choices[i]);
      schemaTypes = $Array.concat(schemaTypes, choiceTypes);
    }
  }
  var ref = schema['$ref'];
  if (ref) {
    var type = this.getOrAddType(ref);
    CHECK(type, 'Could not find type ' + ref);
    schemaTypes = $Array.concat(schemaTypes, this.getAllTypesForSchema(type));
  }
  return schemaTypes;
};

JSONSchemaValidator.prototype.getOrAddType = function(typeName) {
  if (!this.types[typeName])
    this.types[typeName] = loadTypeSchema(typeName);
  return this.types[typeName];
};

/**
 * Returns true if |schema| would accept an argument of type |type|.
 */
JSONSchemaValidator.prototype.isValidSchemaType = function(type, schema) {
  if (type == 'any')
    return true;

  // TODO(kalman): I don't understand this code. How can type be "null"?
  if (schema.optional && (type == "null" || type == "undefined"))
    return true;

  var schemaTypes = this.getAllTypesForSchema(schema);
  for (var i = 0; i < schemaTypes.length; i++) {
    if (schemaTypes[i] == "any" || type == schemaTypes[i])
      return true;
  }

  return false;
};

/**
 * Returns true if there is a non-null argument that both |schema1| and
 * |schema2| would accept.
 */
JSONSchemaValidator.prototype.checkSchemaOverlap = function(schema1, schema2) {
  var schema1Types = this.getAllTypesForSchema(schema1);
  for (var i = 0; i < schema1Types.length; i++) {
    if (this.isValidSchemaType(schema1Types[i], schema2))
      return true;
  }
  return false;
};

/**
 * Validates an instance against a schema. The instance can be any JavaScript
 * value and will be validated recursively. When this method returns, the
 * |errors| property will contain a list of errors, if any.
 */
JSONSchemaValidator.prototype.validate = function(instance, schema, opt_path) {
  var path = opt_path || "";

  if (!schema) {
    this.addError(path, "schemaRequired");
    return;
  }

  // If this schema defines itself as reference type, save it in this.types.
  if (schema.id)
    this.types[schema.id] = schema;

  // If the schema has an extends property, the instance must validate against
  // that schema too.
  if (schema.extends)
    this.validate(instance, schema.extends, path);

  // If the schema has a $ref property, the instance must validate against
  // that schema too. It must be present in this.types to be referenced.
  var ref = schema["$ref"];
  if (ref) {
    if (!this.getOrAddType(ref))
      this.addError(path, "unknownSchemaReference", [ ref ]);
    else
      this.validate(instance, this.getOrAddType(ref), path)
  }

  // If the schema has a choices property, the instance must validate against at
  // least one of the items in that array.
  if (schema.choices) {
    this.validateChoices(instance, schema, path);
    return;
  }

  // If the schema has an enum property, the instance must be one of those
  // values.
  if (schema.enum) {
    if (!this.validateEnum(instance, schema, path))
      return;
  }

  if (schema.type && schema.type != "any") {
    if (!this.validateType(instance, schema, path))
      return;

    // Type-specific validation.
    switch (schema.type) {
      case "object":
        this.validateObject(instance, schema, path);
        break;
      case "array":
        this.validateArray(instance, schema, path);
        break;
      case "string":
        this.validateString(instance, schema, path);
        break;
      case "number":
      case "integer":
        this.validateNumber(instance, schema, path);
        break;
    }
  }
};

/**
 * Validates an instance against a choices schema. The instance must match at
 * least one of the provided choices.
 */
JSONSchemaValidator.prototype.validateChoices =
    function(instance, schema, path) {
  var originalErrors = this.errors;

  for (var i = 0; i < schema.choices.length; i++) {
    this.errors = [];
    this.validate(instance, schema.choices[i], path);
    if (this.errors.length == 0) {
      this.errors = originalErrors;
      return;
    }
  }

  this.errors = originalErrors;
  this.addError(path, "invalidChoice");
};

/**
 * Validates an instance against a schema with an enum type. Populates the
 * |errors| property, and returns a boolean indicating whether the instance
 * validates.
 */
JSONSchemaValidator.prototype.validateEnum = function(instance, schema, path) {
  for (var i = 0; i < schema.enum.length; i++) {
    if (instance === enumToString(schema.enum[i]))
      return true;
  }

  this.addError(path, "invalidEnum",
                [schema.enum.map(enumToString).join(", ")]);
  return false;
};

/**
 * Validates an instance against an object schema and populates the errors
 * property.
 */
JSONSchemaValidator.prototype.validateObject =
    function(instance, schema, path) {
  if (schema.properties) {
    for (var prop in schema.properties) {
      // It is common in JavaScript to add properties to Object.prototype. This
      // check prevents such additions from being interpreted as required
      // schema properties.
      // TODO(aa): If it ever turns out that we actually want this to work,
      // there are other checks we could put here, like requiring that schema
      // properties be objects that have a 'type' property.
      if (!$Object.hasOwnProperty(schema.properties, prop))
        continue;

      var propPath = path ? path + "." + prop : prop;
      if (schema.properties[prop] == undefined) {
        this.addError(propPath, "invalidPropertyType");
      } else if (prop in instance && !isOptionalValue(instance[prop])) {
        this.validate(instance[prop], schema.properties[prop], propPath);
      } else if (!schema.properties[prop].optional) {
        this.addError(propPath, "propertyRequired");
      }
    }
  }

  // If "instanceof" property is set, check that this object inherits from
  // the specified constructor (function).
  if (schema.isInstanceOf) {
    if (!isInstanceOfClass(instance, schema.isInstanceOf))
      this.addError(propPath, "notInstance", [schema.isInstanceOf]);
  }

  // Exit early from additional property check if "type":"any" is defined.
  if (schema.additionalProperties &&
      schema.additionalProperties.type &&
      schema.additionalProperties.type == "any") {
    return;
  }

  // By default, additional properties are not allowed on instance objects. This
  // can be overridden by setting the additionalProperties property to a schema
  // which any additional properties must validate against.
  for (var prop in instance) {
    if (schema.properties && prop in schema.properties)
      continue;

    // Any properties inherited through the prototype are ignored.
    if (!$Object.hasOwnProperty(instance, prop))
      continue;

    var propPath = path ? path + "." + prop : prop;
    if (schema.additionalProperties)
      this.validate(instance[prop], schema.additionalProperties, propPath);
    else
      this.addError(propPath, "unexpectedProperty");
  }
};

/**
 * Validates an instance against an array schema and populates the errors
 * property.
 */
JSONSchemaValidator.prototype.validateArray = function(instance, schema, path) {
  var typeOfItems = JSONSchemaValidator.getType(schema.items);

  if (typeOfItems == 'object') {
    if (schema.minItems && instance.length < schema.minItems) {
      this.addError(path, "arrayMinItems", [schema.minItems]);
    }

    if (typeof schema.maxItems != "undefined" &&
        instance.length > schema.maxItems) {
      this.addError(path, "arrayMaxItems", [schema.maxItems]);
    }

    // If the items property is a single schema, each item in the array must
    // have that schema.
    for (var i = 0; i < instance.length; i++) {
      this.validate(instance[i], schema.items, path + "." + i);
    }
  } else if (typeOfItems == 'array') {
    // If the items property is an array of schemas, each item in the array must
    // validate against the corresponding schema.
    for (var i = 0; i < schema.items.length; i++) {
      var itemPath = path ? path + "." + i : String(i);
      if (i in instance && !isOptionalValue(instance[i])) {
        this.validate(instance[i], schema.items[i], itemPath);
      } else if (!schema.items[i].optional) {
        this.addError(itemPath, "itemRequired");
      }
    }

    if (schema.additionalProperties) {
      for (var i = schema.items.length; i < instance.length; i++) {
        var itemPath = path ? path + "." + i : String(i);
        this.validate(instance[i], schema.additionalProperties, itemPath);
      }
    } else {
      if (instance.length > schema.items.length) {
        this.addError(path, "arrayMaxItems", [schema.items.length]);
      }
    }
  }
};

/**
 * Validates a string and populates the errors property.
 */
JSONSchemaValidator.prototype.validateString =
    function(instance, schema, path) {
  if (schema.minLength && instance.length < schema.minLength)
    this.addError(path, "stringMinLength", [schema.minLength]);

  if (schema.maxLength && instance.length > schema.maxLength)
    this.addError(path, "stringMaxLength", [schema.maxLength]);

  if (schema.pattern && !schema.pattern.test(instance))
    this.addError(path, "stringPattern", [schema.pattern]);
};

/**
 * Validates a number and populates the errors property. The instance is
 * assumed to be a number.
 */
JSONSchemaValidator.prototype.validateNumber =
    function(instance, schema, path) {
  // Forbid NaN, +Infinity, and -Infinity.  Our APIs don't use them, and
  // JSON serialization encodes them as 'null'.  Re-evaluate supporting
  // them if we add an API that could reasonably take them as a parameter.
  if (isNaN(instance) ||
      instance == Number.POSITIVE_INFINITY ||
      instance == Number.NEGATIVE_INFINITY )
    this.addError(path, "numberFiniteNotNan", [instance]);

  if (schema.minimum !== undefined && instance < schema.minimum)
    this.addError(path, "numberMinValue", [schema.minimum]);

  if (schema.maximum !== undefined && instance > schema.maximum)
    this.addError(path, "numberMaxValue", [schema.maximum]);

  // Check for integer values outside of -2^31..2^31-1.
  if (schema.type === "integer" && (instance | 0) !== instance)
    this.addError(path, "numberIntValue", []);

  if (schema.maxDecimal && instance * Math.pow(10, schema.maxDecimal) % 1)
    this.addError(path, "numberMaxDecimal", [schema.maxDecimal]);
};

/**
 * Validates the primitive type of an instance and populates the errors
 * property. Returns true if the instance validates, false otherwise.
 */
JSONSchemaValidator.prototype.validateType = function(instance, schema, path) {
  var actualType = JSONSchemaValidator.getType(instance);
  if (schema.type == actualType ||
      (schema.type == "number" && actualType == "integer")) {
    return true;
  } else if (schema.type == "integer" && actualType == "number") {
    this.addError(path, "invalidTypeIntegerNumber");
    return false;
  } else {
    this.addError(path, "invalidType", [schema.type, actualType]);
    return false;
  }
};

/**
 * Adds an error message. |key| is an index into the |messages| object.
 * |replacements| is an array of values to replace '*' characters in the
 * message.
 */
JSONSchemaValidator.prototype.addError = function(path, key, replacements) {
  $Array.push(this.errors, {
    path: path,
    message: JSONSchemaValidator.formatError(key, replacements)
  });
};

/**
 * Resets errors to an empty list so you can call 'validate' again.
 */
JSONSchemaValidator.prototype.resetErrors = function() {
  this.errors = [];
};

exports.JSONSchemaValidator = JSONSchemaValidator;
