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

var chrome = chrome || {};

// TODO(akalin): Add mocking code for e.g. chrome.send() so that we
// can test this without rebuilding chrome.

/**
 * Organize sync event listeners and asynchronous requests.
 * This object is one of a kind; its constructor is not public.
 * @type {Object}
 */
chrome.sync = chrome.sync || {};
(function() {

// This Event class is a simplified version of the one from
// event_bindings.js.
function Event() {
  this.listeners_ = [];
}

Event.prototype.addListener = function(listener) {
  this.listeners_.push(listener);
};

Event.prototype.removeListener = function(listener) {
  var i = this.findListener_(listener);
  if (i == -1) {
    return;
  }
  this.listeners_.splice(i, 1);
};

Event.prototype.hasListener = function(listener) {
  return this.findListener_(listener) > -1;
};

Event.prototype.hasListeners = function(listener) {
  return this.listeners_.length > 0;
};

// Returns the index of the given listener, or -1 if not found.
Event.prototype.findListener_ = function(listener) {
  for (var i = 0; i < this.listeners_.length; i++) {
    if (this.listeners_[i] == listener) {
      return i;
    }
  }
  return -1;
};

// Fires the event.  Called by the actual event callback.  Any
// exceptions thrown by a listener are caught and logged.
Event.prototype.fire = function() {
  var args = Array.prototype.slice.call(arguments);
  for (var i = 0; i < this.listeners_.length; i++) {
    try {
      this.listeners_[i].apply(null, args);
    } catch (e) {
      if (e instanceof Error) {
        // Non-standard, but useful.
        console.error(e.stack);
      } else {
        console.error(e);
      }
    }
  }
};

chrome.sync.events = {
  'service': [
    'onServiceStateChanged'
  ],

  // See chrome/browser/sync/engine/syncapi.h for docs.
  'notifier': [
    'onNotificationStateChange',
    'onIncomingNotification'
  ],

  'manager': [
    'onChangesApplied',
    'onChangesComplete',
    'onSyncCycleCompleted',
    'onConnectionStatusChange',
    'onPassphraseRequired',
    'onPassphraseAccepted',
    'onInitializationComplete',
    'onStopSyncingPermanently',
    'onClearServerDataSucceeded',
    'onClearServerDataFailed',
    'onEncryptedTypesChanged',
    'onEncryptionComplete',
    'onActionableError',
  ],

  'transaction': [
    'onTransactionWrite',
  ]
};

for (var eventType in chrome.sync.events) {
  var events = chrome.sync.events[eventType];
  for (var i = 0; i < events.length; ++i) {
    var event = events[i];
    chrome.sync[event] = new Event();
  }
}

function makeSyncFunction(name) {
  var callbacks = [];

  // Calls the function, assuming the last argument is a callback to be
  // called with the return value.
  var fn = function() {
    var args = Array.prototype.slice.call(arguments);
    callbacks.push(args.pop());
    chrome.send(name, args);
  };

  // Handle a reply, assuming that messages are processed in FIFO order.
  // Called by SyncInternalsUI::HandleJsReply().
  fn.handleReply = function() {
    var args = Array.prototype.slice.call(arguments);
    // Remove the callback before we call it since the callback may
    // throw.
    var callback = callbacks.shift();
    callback.apply(null, args);
  };

  return fn;
}

var syncFunctions = [
  // Sync service functions.
  'getAboutInfo',

  // Notification functions.  See chrome/browser/sync/engine/syncapi.h
  // for docs.
  'getNotificationState',
  'getNotificationInfo',

  // Client server communication logging functions.
  'getClientServerTraffic',

  // Node lookup functions.  See chrome/browser/sync/engine/syncapi.h
  // for docs.
  'getRootNodeDetails',
  'getNodeSummariesById',
  'getNodeDetailsById',
  'getChildNodeIds',
  'getAllNodes',
];

for (var i = 0; i < syncFunctions.length; ++i) {
  var syncFunction = syncFunctions[i];
  chrome.sync[syncFunction] = makeSyncFunction(syncFunction);
}

/**
 * Returns an object which measures elapsed time.
 */
chrome.sync.makeTimer = function() {
  var start = new Date();

  return {
    /**
     * @return {number} The number of seconds since the timer was
     * created.
     */
    get elapsedSeconds() {
      return ((new Date()).getTime() - start.getTime()) / 1000.0;
    }
  };
};

})();
