// Copyright 2017 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 CHECK = requireNative('logging').CHECK;
var eventBindings = bindingUtil ? undefined : require('event_bindings');
var idGeneratorNatives = requireNative('id_generator');
var utils = require('utils');
var validate = bindingUtil ? undefined : require('schemaUtils').validate;
var webRequestInternal = getInternalApi ?
    getInternalApi('webRequestInternal') :
    require('binding').Binding.create('webRequestInternal').generate();

function validateListenerArguments(
    eventName, extraArgSchemas, listenerArguments) {
  if (bindingUtil)
    bindingUtil.validateCustomSignature(eventName, listenerArguments);
  else
    validate(listenerArguments, extraArgSchemas);
}

function getUniqueSubEventName(eventName) {
  return eventName + '/' + idGeneratorNatives.GetNextId();
}

function createSubEvent(name, argSchemas) {
  if (bindingUtil) {
    var supportsFilters = false;
    var supportsLazyListeners = true;
    return bindingUtil.createCustomEvent(name, undefined,
                                         supportsFilters,
                                         supportsLazyListeners);
  }
  return new eventBindings.Event(name, argSchemas);
}

// WebRequestEventImpl object. This is used for special webRequest events
// with extra parameters. Each invocation of addListener creates a new named
// sub-event. That sub-event is associated with the extra parameters in the
// browser process, so that only it is dispatched when the main event occurs
// matching the extra parameters.
// Note: this is not used for the onActionIgnored event.
//
// Example:
//   chrome.webRequest.onBeforeRequest.addListener(
//       callback, {urls: 'http://*.google.com/*'});
//   ^ callback will only be called for onBeforeRequests matching the filter.
function WebRequestEventImpl(eventName, opt_argSchemas, opt_extraArgSchemas,
                             opt_eventOptions, opt_webViewInstanceId) {
  if (typeof eventName != 'string')
    throw new Error('chrome.WebRequestEvent requires an event name.');

  if (bindingUtil)
    bindingUtil.addCustomSignature(eventName, opt_extraArgSchemas);

  this.eventName = eventName;
  this.argSchemas = opt_argSchemas;
  this.extraArgSchemas = opt_extraArgSchemas;
  this.webViewInstanceId = opt_webViewInstanceId || 0;
  this.subEvents = [];
  if (eventBindings) {
    var eventOptions = eventBindings.parseEventOptions(opt_eventOptions);
    CHECK(!eventOptions.supportsRules, eventName + ' supports rules');
    CHECK(eventOptions.supportsListeners,
          eventName + ' does not support listeners');
  }
}
$Object.setPrototypeOf(WebRequestEventImpl.prototype, null);

// Test if the given callback is registered for this event.
WebRequestEventImpl.prototype.hasListener = function(cb) {
  return this.findListener_(cb) > -1;
};

// Test if any callbacks are registered fur thus event.
WebRequestEventImpl.prototype.hasListeners = function() {
  return this.subEvents.length > 0;
};

// Registers a callback to be called when this event is dispatched. If
// opt_filter is specified, then the callback is only called for events that
// match the given filters. If opt_extraInfo is specified, the given optional
// info is sent to the callback.
WebRequestEventImpl.prototype.addListener =
    function(cb, opt_filter, opt_extraInfo) {
  // NOTE(benjhayden) New APIs should not use this subEventName trick! It does
  // not play well with event pages. See downloads.onDeterminingFilename and
  // ExtensionDownloadsEventRouter for an alternative approach.
  var subEventName = getUniqueSubEventName(this.eventName);
  // Note: this could fail to validate, in which case we would not add the
  // subEvent listener.
  validateListenerArguments(this.eventName, this.extraArgSchemas,
                            $Array.slice(arguments, 1));
  webRequestInternal.addEventListener(
      cb, opt_filter, opt_extraInfo, this.eventName, subEventName,
      this.webViewInstanceId);

  var subEvent = createSubEvent(subEventName, this.argSchemas);
  var subEventCallback = cb;
  if (opt_extraInfo && $Array.indexOf(opt_extraInfo, 'blocking') >= 0) {
    var eventName = this.eventName;
    var webViewInstanceId = this.webViewInstanceId;
    subEventCallback = function() {
      var requestId = arguments[0].requestId;
      try {
        var result = $Function.apply(cb, null, arguments);
        webRequestInternal.eventHandled(
            eventName, subEventName, requestId, webViewInstanceId, result);
      } catch (e) {
        webRequestInternal.eventHandled(
            eventName, subEventName, requestId, webViewInstanceId);
        throw e;
      }
    };
  } else if (
      opt_extraInfo && $Array.indexOf(opt_extraInfo, 'asyncBlocking') >= 0) {
    var eventName = this.eventName;
    var webViewInstanceId = this.webViewInstanceId;
    subEventCallback = function() {
      var details = arguments[0];
      var requestId = details.requestId;
      var handledCallback = function(response) {
        webRequestInternal.eventHandled(
            eventName, subEventName, requestId, webViewInstanceId, response);
      };
      $Function.apply(cb, null, [details, handledCallback]);
    };
  }
  $Array.push(this.subEvents,
      {subEvent: subEvent, callback: cb, subEventCallback: subEventCallback});
  subEvent.addListener(subEventCallback);
};

// Unregisters a callback.
WebRequestEventImpl.prototype.removeListener = function(cb) {
  var idx;
  while ((idx = this.findListener_(cb)) >= 0) {
    var e = this.subEvents[idx];
    e.subEvent.removeListener(e.subEventCallback);
    if (e.subEvent.hasListeners()) {
      console.error(
          'Internal error: webRequest subEvent has orphaned listeners.');
    }
    $Array.splice(this.subEvents, idx, 1);
  }
};

WebRequestEventImpl.prototype.findListener_ = function(cb) {
  for (var i in this.subEvents) {
    var e = this.subEvents[i];
    if (e.callback === cb) {
      if (e.subEvent.hasListener(e.subEventCallback))
        return i;
      console.error('Internal error: webRequest subEvent has no callback.');
    }
  }

  return -1;
};

WebRequestEventImpl.prototype.addRules = function(rules, opt_cb) {
  throw new Error('This event does not support rules.');
};

WebRequestEventImpl.prototype.removeRules =
    function(ruleIdentifiers, opt_cb) {
  throw new Error('This event does not support rules.');
};

WebRequestEventImpl.prototype.getRules = function(ruleIdentifiers, cb) {
  throw new Error('This event does not support rules.');
};

function WebRequestEvent() {
  privates(WebRequestEvent).constructPrivate(this, arguments);
}

// Our util code requires we construct a new WebRequestEvent via a call to
// 'new WebRequestEvent', which wouldn't work well with calling a v8::Function.
// Provide a wrapper for native bindings to call into.
function createWebRequestEvent(eventName, opt_argSchemas, opt_extraArgSchemas,
                               opt_eventOptions, opt_webViewInstanceId) {
  return new WebRequestEvent(eventName, opt_argSchemas, opt_extraArgSchemas,
                             opt_eventOptions, opt_webViewInstanceId);
}

utils.expose(WebRequestEvent, WebRequestEventImpl, {
  functions: [
    'hasListener',
    'hasListeners',
    'addListener',
    'removeListener',
    'addRules',
    'removeRules',
    'getRules',
  ],
});

exports.$set('WebRequestEvent', WebRequestEvent);
exports.$set('createWebRequestEvent', createWebRequestEvent);
