//
// BitGo JavaScript SDK
//
// Copyright 2014, BitGo, Inc.  All Rights Reserved.
//

var superagent = require('superagent');
var Address = require('./bitcoin/address');
var Keychains = require('./keychains');
var Wallets = require('./wallets');
var sjcl = require('./bitcoin/sjcl.min');

//
// Constructor for BitGo Object
// arguments:
//   @useProduction: flag to use the production bitcoin network rather than the
//                   testnet network.
//
var BitGo = function(useProduction) {
  if (useProduction && typeof(useProduction) != 'boolean') {
    throw new Error('invalid argument');
  }

  // By default, we operate on the test server.
  if (useProduction) {
    this._baseUrl = 'https://www.bitgo.com/api/v1';
  } else {
    this._baseUrl = 'https://beer.bitgo.com/api/v1';
  }

  this._user = null;
  this._keychains = null;
  this._wallets = null;

  // Create superagent methods specific to this BitGo instance.
  this.request = {};
  var methods = ['get', 'post', 'put', 'del'];

  // This is a patching function which can apply our authorization
  // headers to any outbound request.
  var createPatch = function(method) {
    return function() {
      var req = superagent[method].apply(null, arguments);
      if (self._token) {
        req.set('Authorization', "Bearer " + self._token);
      }
      return req;
    };
  }

  for (var index in methods) {
    var self = this;
    var method = methods[index];
    self[method] = createPatch(method);
  }
};


//
// version
// Gets the version of the BitGoJS API
//
BitGo.prototype.version = function() {
  return '0.1.0';
};

BitGo.prototype.verifyAddress = function(addr) {
  if (typeof(addr) != 'string') {
    throw new Error('invalid argument');
  }
  try {
    var address = new Address(addr);
    return true;
  } catch(e) {
console.log(e);
    return false;
  }
};

//
// encrypt
// Utility function to encrypt locally.
//
BitGo.prototype.encrypt = function(password, string) {
  var encryptOptions = { iter: 10000, ks: 256 };
  return sjcl.encrypt(password, string, encryptOptions);
};

//
// decrypt
// Utility function to decrypt locally.
//
BitGo.prototype.decrypt = function(password, opaque) {
  return sjcl.decrypt(password, opaque);
};

//
// market
// Get the latest bitcoin prices.
//
BitGo.prototype.market = function(callback) {
  if (typeof(callback) != 'function') {
    throw new Error('invalid argument');
  }

  var url = this._baseUrl + '/market/latest';
  this.get(url)
  .end(function(err, res) {
    if (err) {
      return callback(err);
    }
    callback(null, res.body);
  });
};

//
// authenticate
// Login to the bitgo system.
// Returns:
//   {
//     token: <user's token>,
//     user: <user object
//   }
BitGo.prototype.authenticate = function(username, password, otp, callback) {
  if (typeof(username) != 'string' || typeof(password) != 'string' ||
      typeof(otp) != 'string' || typeof(callback) != 'function') {
    throw new Error('illegal argument');
  }

  var self = this;
  var url = this._baseUrl + '/user/login';

  if (this._user) {
    return callback(new Error('already logged in'));
  }

  this.post(url)
  .send({email: username, password: password, otp: otp})
  .end(function(err, res) {
    if (self.handleBitGoAPIError(err, res, callback)) {
      return;
    }
    self._user = res.body.user;
    self._token = res.body.access_token;
    callback(null, res.body);
  });
};

//
// logout
// Logout of BitGo
//
BitGo.prototype.logout = function(callback) {
  if (typeof(callback) != 'function') {
    throw new Error('invalid argument');
  }

  if (!this._user) {
    return callback(null);  // We're not logged in.
  }

  var self = this;
  var url = this._baseUrl + '/user/logout';
  this.get(url)
  .send()
  .end(function(err, res) {
    delete self._user;
    delete self._token;
    callback(err);
  });
};

//
// me
// Get the current logged in user
//
BitGo.prototype.me = function(callback) {
  if (typeof(callback) != 'function') {
    throw new Error('invalid argument');
  }

  if (!this._user) {
    return callback(new Error('not authenticated'));
  }

  var url = this._baseUrl + '/user/me';
  var self = this;
  this.get(url)
  .send()
  .end(function(err, res) {
    if (self.handleBitGoAPIError(err, res, callback)) {
      return;
    }
    callback(null, res.body.user);
  });
};

//
// keychains
// Get the user's keychains object.
//
BitGo.prototype.keychains = function() {
  if (!this._keychains) {
    this._keychains = new Keychains(this);
  }
  return this._keychains;
};

//
// wallets
// Get the user's wallets object.
//
BitGo.prototype.wallets = function() {
  if (!this._wallets) {
    this._wallets = new Wallets(this);
  }
  return this._wallets;
};

//
// Handles HTTP errors from the BitGo API
// Returns:
//   true if an error was handled and the callback was called.  The caller should stop processing.
//   false if the caller should continue.
//
BitGo.prototype.handleBitGoAPIError = function(err, res, callback) {
  if (err) {
    // TODO: assert type of err object?
    callback(err);
    return;
  }

  if (res.status == 200) {
    return false;   // no error!
  }

  if (res.status == 401 && res.body.needsOTP) {
    callback({status: 401, needsOTP: true});
    return true;
  }

  var error = res.body.error ? res.body.error : res.status.toString();
  callback({status: res.status, error: error, details: new Error(error)});
  return true;
}

module.exports = BitGo;

@@ -765,12 +765,12 @@
 s://
-beer
+test
 .bit
@@ -1804,24 +1804,8 @@
 ) %7B%0A
-console.log(e);%0A
     
@@ -4261,32 +4261,33 @@
   return;%0A    %7D%0A
+%0A
     callback(nul
@@ -5047,24 +5047,29 @@
 ;%0A    return
+ true
 ;%0A  %7D%0A%0A  if 

Fix baseUrl; remove console log.