var Settings = require('settings');
var ajax = require('ajax');

var GApi = {
  updateConfiguration: function(e) {
    var data = Settings.data() || {};

    /* Remove old accounts */
    if ('accounts' in e.options) {
      var accounts = e.options.accounts || [];
      for (var key in data) {
        if (key == 'secret') {
          continue;
        }
        var keep = false;
        for (var i = 0; i < accounts.length; i++) {
          if (accounts[i].key == key) {
            keep = true;
            break;
          }
        }
        if (!keep) {
          data[key] = null;
        }
      }
    }

    /* Keep secret */
    if ('secret' in e.options) {
      if (!e.options.secret) {
        data.secret = null;
      } else if (e.options.secret.length == 24) {
        data.secret = e.options.secret;
        Settings.option('secret', 'y');
      }
    }

    /* Save the data */
    Settings.data(data);

    if (this.onUpdate) {
      this.onUpdate();
    }
  },

  getAccessToken: function(account, callback, errorCallback) {
    if (!account || !account.key) {
      if (errorCallback) errorCallback('No account available');
      return;
    }
    var oauth = Settings.data(account.key);
    var now = new Date();
    var expiry = 0;
    if (oauth) {
      expiry = (oauth.created + oauth.expires_in) * 1000;
    }
    if (now.valueOf() < expiry) {
      callback(oauth.access_token);
    } else {
      var request = { 'client_id': Settings.option('clientId'),
                      'client_secret': Settings.data('secret') };
      if (!oauth) {
        request.grant_type = "authorization_code";
        request.redirect_uri = "urn:ietf:wg:oauth:2.0:oob";
        request.code = account.key;
      } else {
        request.grant_type = "refresh_token";
        request.refresh_token = oauth.refresh_token;
      }
      ajax({
        url: "https://www.googleapis.com/oauth2/v3/token",
        method: 'post',
        data: request
      }, function(data) {
        data = JSON.parse(data);
        if (data && data.access_token) {
          oauth = oauth || {};
          for (var key in data) {
            oauth[key] = data[key];
          }
          oauth.created = now.valueOf() / 1000;
          Settings.data(account.key, oauth);
          callback(oauth.access_token);
        } else {
          if (errorCallback) errorCallback('Could not acquire access token');
        }
      }, function(error) {
        if (errorCallback) errorCallback('Could not request access token');
      });
    }
  }
};

module.exports = GApi;

@@ -975,16 +975,842 @@
   %7D%0A  %7D,
+%0A  %0A  /* Queues callbacks in case multiple requests are in parallel */%0A  callbackQueue: %7B%0A    queue: %7B%7D,%0A    %0A    push: function(account, callback, errorCallback) %7B%0A      this.queue%5Baccount.key%5D = this.queue%5Baccount.key%5D %7C%7C %5B%5D;%0A      this.queue%5Baccount.key%5D.push(%5Bcallback, errorCallback%5D);%0A      return this.queue%5Baccount.key%5D.length %3E 1;%0A    %7D,%0A    %0A    doCallbacks: function(index, account, data) %7B%0A      var callbacks = this.queue%5Baccount.key%5D;%0A      for (var i = 0; i %3C callbacks.length; i++) %7B%0A        if (callbacks%5Bi%5D%5Bindex%5D) %7B%0A          callbacks%5Bi%5D%5Bindex%5D(data);%0A        %7D%0A      %7D%0A      delete this.queue%5Baccount.key%5D;%0A    %7D,%0A    %0A    callback: function(account, data) %7B%0A      this.doCallbacks(0, account, data);%0A    %7D,%0A    errorCallback: function(account, data) %7B%0A      this.doCallbacks(1, account, data);%0A    %7D%0A  %7D,
 %0A%0A  getA
@@ -1946,28 +1946,37 @@
 ck('
-No a
+A
 ccount 
-available
+configuration invalid
 ');%0A
@@ -2245,24 +2245,119 @@
    %7D else %7B%0A
+      if (GApi.callbackQueue.push(account, callback, errorCallback)) %7B%0A        return;%0A      %7D%0A
       var re
@@ -3193,33 +3193,61 @@
 ;%0A          
-callback(
+GApi.callbackQueue.callback(account, 
 oauth.access
@@ -3282,35 +3282,35 @@
         
-if (errorC
+GApi.c
 allback
-) 
+Queue.
 errorCal
@@ -3307,32 +3307,41 @@
 e.errorCallback(
+account, 
 'Could not acqui
@@ -3404,35 +3404,35 @@
         
-if (errorC
+GApi.c
 allback
-) 
+Queue.
 errorCal
@@ -3437,16 +3437,25 @@
 allback(
+account, 
 'Could n

Fix refreshing access when reusing auth tokens