var request = require('request');
var api     = require('./api');

function Client(options) {

  var fieldsToValidate = !options.accessToken ?
    ['domain', 'clientID', 'clientSecret'] :
    ['domain'];

  fieldsToValidate.forEach(function (k) {
    if(!options[k]){
      throw new Error(k + ' is required');
    }
  });

  this.apiUrl =   'https://' + options.domain + '/api';
  this.tokenUrl = 'https://' + options.domain + '/oauth/token';
  this.options = options;
}

Client.prototype._getAccessToken = function(done){
  var body = {
    'client_id':     this.options.clientID,
    'client_secret': this.options.clientSecret,
    'grant_type':    'client_credentials'
  };

  request.post({
    url: this.tokenUrl,
    form: body
  }, function (err, resp, body) {

    if (err) return done(err);
    if (resp.statusCode === 404) return done(new Error('unknown client'));
    if (resp.statusCode.toString().substr(0, 1) !== '2') return done(new Error(body));

    var accessToken = JSON.parse(body)['access_token'];
    done(null, accessToken);
  });
};

Object.keys(api).forEach(function (m) {
  Client.prototype[m] = function (){
    var args = [].slice.call(arguments);
    var callback = args[args.length - 1];
    
    if (this.options.accessToken) {
      api[m].apply(this, [this.options.accessToken].concat(args));
    }
    else {
      this._getAccessToken(function (err, accessToken) {
        if (err) return callback(err);
        api[m].apply(this, [accessToken].concat(args));
      }.bind(this));
    }
  };
});

module.exports = Client;
@@ -477,19 +477,8 @@
 ent.
-prototype._
 getA
@@ -502,14 +502,25 @@
 tion
-(
+ (options, 
 done)
+ 
 %7B%0A  
@@ -553,21 +553,16 @@
 d':     
-this.
 options.
@@ -592,21 +592,16 @@
 ecret': 
-this.
 options.
@@ -660,16 +660,82 @@
 ls'%0A  %7D;
+%0A  %0A  var tokenUrl = 'https://' + options.domain + '/oauth/token';
 %0A%0A  requ
@@ -754,21 +754,17 @@
    url: 
-this.
+ 
 tokenUrl
@@ -1104,16 +1104,446 @@
 %7D);%0A%7D;%0A%0A
+Client.prototype._getAccessToken = function(done)%7B%0A  var self = this;%0A%0A  if (this._currentAccessToken) return done(null, this._currentAccessToken);%0A%0A  return Client.getAccessToken(this.options, function (err, token) %7B%0A    if (err) return done(err);%0A%0A    self._currentAccessToken = token;%0A%0A    setTimeout(function () %7B%0A      delete self._currentAccessToken;%0A    %7D, 1000 * 60 * 3); //~ 3 hours%0A    %0A    done(null, token);%0A  %7D);%0A%7D;%0A%0A
 Object.k

add Client.getAccessToken