// Copyright 2014 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.

var Event = require('event_bindings').Event;
var forEach = require('utils').forEach;
// Note: Beware sneaky getters/setters when using GetAvailbility(). Use safe/raw
// variables as arguments.
var GetAvailability = requireNative('v8_context').GetAvailability;
var exceptionHandler = require('uncaught_exception_handler');
var lastError = require('lastError');
var logActivity = requireNative('activityLogger');
var logging = requireNative('logging');
var process = requireNative('process');
var schemaRegistry = requireNative('schema_registry');
var schemaUtils = require('schemaUtils');
var utils = require('utils');
var sendRequestHandler = require('sendRequest');

var contextType = process.GetContextType();
var extensionId = process.GetExtensionId();
var manifestVersion = process.GetManifestVersion();
var sendRequest = sendRequestHandler.sendRequest;

// Stores the name and definition of each API function, with methods to
// modify their behaviour (such as a custom way to handle requests to the
// API, a custom callback, etc).
function APIFunctions(namespace) {
  this.apiFunctions_ = {};
  this.unavailableApiFunctions_ = {};
  this.namespace = namespace;
}

APIFunctions.prototype.register = function(apiName, apiFunction) {
  this.apiFunctions_[apiName] = apiFunction;
};

// Registers a function as existing but not available, meaning that calls to
// the set* methods that reference this function should be ignored rather
// than throwing Errors.
APIFunctions.prototype.registerUnavailable = function(apiName) {
  this.unavailableApiFunctions_[apiName] = apiName;
};

APIFunctions.prototype.setHook_ =
    function(apiName, propertyName, customizedFunction) {
  if ($Object.hasOwnProperty(this.unavailableApiFunctions_, apiName))
    return;
  if (!$Object.hasOwnProperty(this.apiFunctions_, apiName))
    throw new Error('Tried to set hook for unknown API "' + apiName + '"');
  this.apiFunctions_[apiName][propertyName] = customizedFunction;
};

APIFunctions.prototype.setHandleRequest =
    function(apiName, customizedFunction) {
  var prefix = this.namespace;
  return this.setHook_(apiName, 'handleRequest',
    function() {
      var ret = $Function.apply(customizedFunction, this, arguments);
      // Logs API calls to the Activity Log if it doesn't go through an
      // ExtensionFunction.
      if (!sendRequestHandler.getCalledSendRequest())
        logActivity.LogAPICall(extensionId, prefix + "." + apiName,
            $Array.slice(arguments));
      return ret;
    });
};

APIFunctions.prototype.setHandleRequestWithPromise =
    function(apiName, customizedFunction) {
  var prefix = this.namespace;
  return this.setHook_(apiName, 'handleRequest', function() {
      var name = prefix + '.' + apiName;
      logActivity.LogAPICall(extensionId, name, $Array.slice(arguments));
      var stack = exceptionHandler.getExtensionStackTrace();
      var callback = arguments[arguments.length - 1];
      var args = $Array.slice(arguments, 0, arguments.length - 1);
      var keepAlivePromise = requireAsync('keep_alive').then(function(module) {
        return module.createKeepAlive();
      });
      $Function.apply(customizedFunction, this, args).then(function(result) {
        if (callback) {
          sendRequestHandler.safeCallbackApply(name, {'stack': stack}, callback,
                                               [result]);
        }
      }).catch(function(error) {
        if (callback) {
          var message = exceptionHandler.safeErrorToString(error, true);
          lastError.run(name, message, stack, callback);
        }
      }).then(function() {
        keepAlivePromise.then(function(keepAlive) {
          keepAlive.close();
        });
      });
    });
};

APIFunctions.prototype.setUpdateArgumentsPostValidate =
    function(apiName, customizedFunction) {
  return this.setHook_(
    apiName, 'updateArgumentsPostValidate', customizedFunction);
};

APIFunctions.prototype.setUpdateArgumentsPreValidate =
    function(apiName, customizedFunction) {
  return this.setHook_(
    apiName, 'updateArgumentsPreValidate', customizedFunction);
};

APIFunctions.prototype.setCustomCallback =
    function(apiName, customizedFunction) {
  return this.setHook_(apiName, 'customCallback', customizedFunction);
};

function CustomBindingsObject() {
}

CustomBindingsObject.prototype.setSchema = function(schema) {
  // The functions in the schema are in list form, so we move them into a
  // dictionary for easier access.
  var self = this;
  self.functionSchemas = {};
  $Array.forEach(schema.functions, function(f) {
    self.functionSchemas[f.name] = {
      name: f.name,
      definition: f
    }
  });
};

// Get the platform from navigator.appVersion.
function getPlatform() {
  var platforms = [
    [/CrOS Touch/, "chromeos touch"],
    [/CrOS/, "chromeos"],
    [/Linux/, "linux"],
    [/Mac/, "mac"],
    [/Win/, "win"],
  ];

  for (var i = 0; i < platforms.length; i++) {
    if ($RegExp.exec(platforms[i][0], navigator.appVersion)) {
      return platforms[i][1];
    }
  }
  return "unknown";
}

function isPlatformSupported(schemaNode, platform) {
  return !schemaNode.platforms ||
      $Array.indexOf(schemaNode.platforms, platform) > -1;
}

function isManifestVersionSupported(schemaNode, manifestVersion) {
  return !schemaNode.maximumManifestVersion ||
      manifestVersion <= schemaNode.maximumManifestVersion;
}

function isSchemaNodeSupported(schemaNode, platform, manifestVersion) {
  return isPlatformSupported(schemaNode, platform) &&
      isManifestVersionSupported(schemaNode, manifestVersion);
}

function createCustomType(type) {
  var jsModuleName = type.js_module;
  logging.CHECK(jsModuleName, 'Custom type ' + type.id +
                ' has no "js_module" property.');
  // This list contains all types that has a js_module property. It is ugly to
  // hard-code them here, but the number of APIs that use js_module has not
  // changed since the introduction of js_modules in crbug.com/222156.
  // This whitelist serves as an extra line of defence to avoid exposing
  // arbitrary extension modules when the |type| definition is poisoned.
  var whitelistedModules = [
    'ChromeDirectSetting',
    'ChromeSetting',
    'ContentSetting',
    'StorageArea',
  ];
  logging.CHECK($Array.indexOf(whitelistedModules, jsModuleName) !== -1,
                'Module ' + jsModuleName + ' does not define a custom type.');
  var jsModule = require(jsModuleName);
  logging.CHECK(jsModule, 'No module ' + jsModuleName + ' found for ' +
                type.id + '.');
  var customType = jsModule[jsModuleName];
  logging.CHECK(customType, jsModuleName + ' must export itself.');
  customType.prototype = new CustomBindingsObject();
  customType.prototype.setSchema(type);
  return customType;
}

var platform = getPlatform();

function Binding(apiName) {
  this.apiName_ = apiName;
  this.apiFunctions_ = new APIFunctions(apiName);
  this.customEvent_ = null;
  this.customHooks_ = [];
};

Binding.create = function(apiName) {
  return new Binding(apiName);
};

Binding.prototype = {
  // The API through which the ${api_name}_custom_bindings.js files customize
  // their API bindings beyond what can be generated.
  //
  // There are 2 types of customizations available: those which are required in
  // order to do the schema generation (registerCustomEvent and
  // registerCustomType), and those which can only run after the bindings have
  // been generated (registerCustomHook).

  // Registers a custom event type for the API identified by |namespace|.
  // |event| is the event's constructor.
  registerCustomEvent: function(event) {
    this.customEvent_ = event;
  },

  // Registers a function |hook| to run after the schema for all APIs has been
  // generated.  The hook is passed as its first argument an "API" object to
  // interact with, and second the current extension ID. See where
  // |customHooks| is used.
  registerCustomHook: function(fn) {
    $Array.push(this.customHooks_, fn);
  },

  // TODO(kalman/cduvall): Refactor this so |runHooks_| is not needed.
  runHooks_: function(api, schema) {
    $Array.forEach(this.customHooks_, function(hook) {
      if (!isSchemaNodeSupported(schema, platform, manifestVersion))
        return;

      if (!hook)
        return;

      hook({
        apiFunctions: this.apiFunctions_,
        schema: schema,
        compiledApi: api
      }, extensionId, contextType);
    }, this);
  },

  // Generates the bindings from the schema for |this.apiName_| and integrates
  // any custom bindings that might be present.
  generate: function() {
    // NB: It's important to load the schema during generation rather than
    // setting it beforehand so that we're more confident the schema we're
    // loading is real, and not one that was injected by a page intercepting
    // Binding.generate.
    // Additionally, since the schema is an object returned from a native
    // handler, its properties don't have the custom getters/setters that a page
    // may have put on Object.prototype, and the object is frozen by v8.
    var schema = schemaRegistry.GetSchema(this.apiName_);

    function shouldCheckUnprivileged() {
      var shouldCheck = 'unprivileged' in schema;
      if (shouldCheck)
        return shouldCheck;

      $Array.forEach(['functions', 'events'], function(type) {
        if ($Object.hasOwnProperty(schema, type)) {
          $Array.forEach(schema[type], function(node) {
            if ('unprivileged' in node)
              shouldCheck = true;
          });
        }
      });
      if (shouldCheck)
        return shouldCheck;

      for (var property in schema.properties) {
        if ($Object.hasOwnProperty(schema, property) &&
            'unprivileged' in schema.properties[property]) {
          shouldCheck = true;
          break;
        }
      }
      return shouldCheck;
    }
    var checkUnprivileged = shouldCheckUnprivileged();

    // TODO(kalman/cduvall): Make GetAvailability handle this, then delete the
    // supporting code.
    if (!isSchemaNodeSupported(schema, platform, manifestVersion)) {
      console.error('chrome.' + schema.namespace + ' is not supported on ' +
                    'this platform or manifest version');
      return undefined;
    }

    var mod = {};

    var namespaces = $String.split(schema.namespace, '.');
    for (var index = 0, name; name = namespaces[index]; index++) {
      mod[name] = mod[name] || {};
      mod = mod[name];
    }

    if (schema.types) {
      $Array.forEach(schema.types, function(t) {
        if (!isSchemaNodeSupported(t, platform, manifestVersion))
          return;

        // Add types to global schemaValidator; the types we depend on from
        // other namespaces will be added as needed.
        schemaUtils.schemaValidator.addTypes(t);

        // Generate symbols for enums.
        var enumValues = t['enum'];
        if (enumValues) {
          // Type IDs are qualified with the namespace during compilation,
          // unfortunately, so remove it here.
          logging.DCHECK($String.substr(t.id, 0, schema.namespace.length) ==
                             schema.namespace);
          // Note: + 1 because it ends in a '.', e.g., 'fooApi.Type'.
          var id = $String.substr(t.id, schema.namespace.length + 1);
          mod[id] = {};
          $Array.forEach(enumValues, function(enumValue) {
            // Note: enums can be declared either as a list of strings
            // ['foo', 'bar'] or as a list of objects
            // [{'name': 'foo'}, {'name': 'bar'}].
            enumValue = $Object.hasOwnProperty(enumValue, 'name') ?
                enumValue.name : enumValue;
            if (enumValue) {  // Avoid setting any empty enums.
              // Make all properties in ALL_CAPS_STYLE.
              //
              // The built-in versions of $String.replace call other built-ins,
              // which may be clobbered. Instead, manually build the property
              // name.
              //
              // If the first character is a digit (we know it must be one of
              // a digit, a letter, or an underscore), precede it with an
              // underscore.
              var propertyName = ($RegExp.exec(/\d/, enumValue[0])) ? '_' : '';
              for (var i = 0; i < enumValue.length; ++i) {
                var next;
                if (i > 0 && $RegExp.exec(/[a-z]/, enumValue[i-1]) &&
                    $RegExp.exec(/[A-Z]/, enumValue[i])) {
                  // Replace myEnum-Foo with my_Enum-Foo:
                  next = '_' + enumValue[i];
                } else if ($RegExp.exec(/\W/, enumValue[i])) {
                  // Replace my_Enum-Foo with my_Enum_Foo:
                  next = '_';
                } else {
                  next = enumValue[i];
                }
                propertyName += next;
              }
              // Uppercase (replace my_Enum_Foo with MY_ENUM_FOO):
              propertyName = $String.toUpperCase(propertyName);
              mod[id][propertyName] = enumValue;
            }
          });
        }
      }, this);
    }

    // TODO(cduvall): Take out when all APIs have been converted to features.
    // Returns whether access to the content of a schema should be denied,
    // based on the presence of "unprivileged" and whether this is an
    // extension process (versus e.g. a content script).
    function isSchemaAccessAllowed(itemSchema) {
      return (contextType == 'BLESSED_EXTENSION') ||
             schema.unprivileged ||
             itemSchema.unprivileged;
    };

    // Setup Functions.
    if (schema.functions) {
      $Array.forEach(schema.functions, function(functionDef) {
        if (functionDef.name in mod) {
          throw new Error('Function ' + functionDef.name +
                          ' already defined in ' + schema.namespace);
        }

        if (!isSchemaNodeSupported(functionDef, platform, manifestVersion)) {
          this.apiFunctions_.registerUnavailable(functionDef.name);
          return;
        }

        var apiFunction = {};
        apiFunction.definition = functionDef;
        var apiFunctionName = schema.namespace + '.' + functionDef.name;
        apiFunction.name = apiFunctionName;

        if (!GetAvailability(apiFunctionName).is_available ||
            (checkUnprivileged && !isSchemaAccessAllowed(functionDef))) {
          this.apiFunctions_.registerUnavailable(functionDef.name);
          return;
        }

        // TODO(aa): It would be best to run this in a unit test, but in order
        // to do that we would need to better factor this code so that it
        // doesn't depend on so much v8::Extension machinery.
        if (logging.DCHECK_IS_ON() &&
            schemaUtils.isFunctionSignatureAmbiguous(apiFunction.definition)) {
          throw new Error(
              apiFunction.name + ' has ambiguous optional arguments. ' +
              'To implement custom disambiguation logic, add ' +
              '"allowAmbiguousOptionalArguments" to the function\'s schema.');
        }

        this.apiFunctions_.register(functionDef.name, apiFunction);

        mod[functionDef.name] = $Function.bind(function() {
          var args = $Array.slice(arguments);
          if (this.updateArgumentsPreValidate)
            args = $Function.apply(this.updateArgumentsPreValidate, this, args);

          args = schemaUtils.normalizeArgumentsAndValidate(args, this);
          if (this.updateArgumentsPostValidate) {
            args = $Function.apply(this.updateArgumentsPostValidate,
                                   this,
                                   args);
          }

          sendRequestHandler.clearCalledSendRequest();

          var retval;
          if (this.handleRequest) {
            retval = $Function.apply(this.handleRequest, this, args);
          } else {
            var optArgs = {
              customCallback: this.customCallback
            };
            retval = sendRequest(this.name, args,
                                 this.definition.parameters,
                                 optArgs);
          }
          sendRequestHandler.clearCalledSendRequest();

          // Validate return value if in sanity check mode.
          if (logging.DCHECK_IS_ON() && this.definition.returns)
            schemaUtils.validate([retval], [this.definition.returns]);
          return retval;
        }, apiFunction);
      }, this);
    }

    // Setup Events
    if (schema.events) {
      $Array.forEach(schema.events, function(eventDef) {
        if (eventDef.name in mod) {
          throw new Error('Event ' + eventDef.name +
                          ' already defined in ' + schema.namespace);
        }
        if (!isSchemaNodeSupported(eventDef, platform, manifestVersion))
          return;

        var eventName = schema.namespace + "." + eventDef.name;
        if (!GetAvailability(eventName).is_available ||
            (checkUnprivileged && !isSchemaAccessAllowed(eventDef))) {
          return;
        }

        var options = eventDef.options || {};
        if (eventDef.filters && eventDef.filters.length > 0)
          options.supportsFilters = true;

        var parameters = eventDef.parameters;
        if (this.customEvent_) {
          mod[eventDef.name] = new this.customEvent_(
              eventName, parameters, eventDef.extraParameters, options);
        } else {
          mod[eventDef.name] = new Event(eventName, parameters, options);
        }
      }, this);
    }

    function addProperties(m, parentDef) {
      var properties = parentDef.properties;
      if (!properties)
        return;

      forEach(properties, function(propertyName, propertyDef) {
        if (propertyName in m)
          return;  // TODO(kalman): be strict like functions/events somehow.
        if (!isSchemaNodeSupported(propertyDef, platform, manifestVersion))
          return;
        if (!GetAvailability(schema.namespace + "." +
              propertyName).is_available ||
            (checkUnprivileged && !isSchemaAccessAllowed(propertyDef))) {
          return;
        }

        var value = propertyDef.value;
        if (value) {
          // Values may just have raw types as defined in the JSON, such
          // as "WINDOW_ID_NONE": { "value": -1 }. We handle this here.
          // TODO(kalman): enforce that things with a "value" property can't
          // define their own types.
          var type = propertyDef.type || typeof(value);
          if (type === 'integer' || type === 'number') {
            value = parseInt(value);
          } else if (type === 'boolean') {
            value = value === 'true';
          } else if (propertyDef['$ref']) {
            var ref = propertyDef['$ref'];
            var type = utils.loadTypeSchema(propertyDef['$ref'], schema);
            logging.CHECK(type, 'Schema for $ref type ' + ref + ' not found');
            var constructor = createCustomType(type);
            var args = value;
            // For an object propertyDef, |value| is an array of constructor
            // arguments, but we want to pass the arguments directly (i.e.
            // not as an array), so we have to fake calling |new| on the
            // constructor.
            value = { __proto__: constructor.prototype };
            $Function.apply(constructor, value, args);
            // Recursively add properties.
            addProperties(value, propertyDef);
          } else if (type === 'object') {
            // Recursively add properties.
            addProperties(value, propertyDef);
          } else if (type !== 'string') {
            throw new Error('NOT IMPLEMENTED (extension_api.json error): ' +
                'Cannot parse values for type "' + type + '"');
          }
          m[propertyName] = value;
        }
      });
    };

    addProperties(mod, schema);

    // This generate() call is considered successful if any functions,
    // properties, or events were created.
    var success = ($Object.keys(mod).length > 0);

    // Special case: webViewRequest is a vacuous API which just copies its
    // implementation from declarativeWebRequest.
    //
    // TODO(kalman): This would be unnecessary if we did these checks after the
    // hooks (i.e. this.runHooks_(mod)). The reason we don't is to be very
    // conservative with running any JS which might actually be for an API
    // which isn't available, but this is probably overly cautious given the
    // C++ is only giving us APIs which are available. FIXME.
    if (schema.namespace == 'webViewRequest') {
      success = true;
    }

    // Special case: runtime.lastError is only occasionally set, so
    // specifically check its availability.
    if (schema.namespace == 'runtime' &&
        GetAvailability('runtime.lastError').is_available) {
      success = true;
    }

    if (!success) {
      var availability = GetAvailability(schema.namespace);
      // If an API was available it should have been successfully generated.
      logging.DCHECK(!availability.is_available,
                     schema.namespace + ' was available but not generated');
      console.error('chrome.' + schema.namespace + ' is not available: ' +
                    availability.message);
      return;
    }

    this.runHooks_(mod, schema);
    return mod;
  }
};

exports.$set('Binding', Binding);
