<commit_before>'use strict';

var fs = require('fs');
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var async = require('async');
var jsonquest = require('./jsonquest');

var _t0 = null;
var sequenceNumber = 0;

var Trader = function(config) {
  if (!(this instanceof Trader)) return new Trader(config);
  EventEmitter.call(this);

  this.connectionInfo = null;
  this.protocol = config.protocol || 'https';
  this.rejectUnauthorized = typeof config.rejectUnauthorized === 'undefined' ?
    true :
    !!config.rejectUnauthorized;

  this.config = config;
  this.exchangeRate = null;
  this.fiatExchangeRate = null;
  this.balance = null;
  this.locale = null;

  this.exchange = null;
  this.balanceTimer = null;
  this.balanceRetries = 0;
  this.balanceTriggers = null;
  this.tickerExchange = null;
  this.transferExchange = null;
  this.pollTimer = null;
  this.pollRetries = 0;
  this.txLimit = null;
  this.fiatTxLimit = 50;  // TODO: make configurable
  this.idVerificationLimit = null;
  this.idVerificationEnabled = false;
  this.sessionId = null;
  this.twoWayMode = false;
};
util.inherits(Trader, EventEmitter);

Trader.prototype.init = function init(connectionInfo) {
  if (this.protocol === 'https') {
    this.cert = fs.readFileSync(this.config.certs.certFile);
    this.key = fs.readFileSync(this.config.certs.keyFile);
  }
  this.connectionInfo = connectionInfo;

  jsonquest.setEmitter(this.emit);
};

Trader.prototype.pair = function pair(connectionInfo) {
  this.connectionInfo = connectionInfo;
};

Trader.prototype._request = function _request(options, cb) {
  var protocol = this.protocol || 'https';
  var connectionInfo = this.connectionInfo;
  var host = protocol === 'http' ? 'localhost' : connectionInfo.host;
  var fingerprint = protocol === 'http' ? false : connectionInfo.fingerprint;
  var self = this;
  var sessionId = this.sessionId;
  var headers = sessionId ? {'session-id': sessionId} : {};
  if (options.body) headers['content-type'] = 'application/json';

  jsonquest({
    protocol: protocol,
    host: host,
    port: connectionInfo.port,
    cert: this.cert,
    key: this.key,
    rejectUnauthorized: this.rejectUnauthorized,
    method: options.method,
    path: options.path,
    body: options.body,
    headers: headers,
    fingerprint: fingerprint,
    repeatUntilSuccess: options.repeatUntilSuccess
  }, function (err, res, body) {
    if (sessionId && sessionId !== self.sessionId) {
      console.log('WARN: received a response from old sessionId: %s, ' +
        'current is: %s', sessionId, self.sessionId);
      return; // No need to call handler
    }

    if (err) return cb(_richError(err.message, 'networkDown'));

    if (res.statusCode === 404) {
      self.connectionInfo = null;
      return cb(_richError('Server has unpaired', 'unpair'));
    }

    // All 2xx codes are OK
    if (res.statusCode < 200 || res.statusCode >= 300)
      return cb(_richError('Server returned ' + res.statusCode + ': ' + body.err));

    var errRec = body.err ? {name: body.errType, message: body.err} : null;
    var result = body;

    if (errRec) return cb(_richError(errRec.message, errRec.name));
    cb(null, result);
  });
};

Trader.prototype.run = function run() {
  var self = this;

  self.trigger();
  self.triggerInterval = setInterval(function() {
    self.trigger();
  }, this.config.settings.pollInterval);
};

Trader.prototype.stop = function stop() {
  if (this.triggerInterval) clearInterval(this.triggerInterval);
};

Trader.prototype.verifyUser = function verifyUser(idRec, cb) {
  console.log(idRec);
  this._request({
    path: '/verify_user',
    method: 'POST',
    body: idRec
  }, cb);
};

Trader.prototype.verifyTransaction = function verifyTransaction(idRec) {
  console.log(idRec);
  this._request({
    path: '/verify_transaction',
    method: 'POST',
    body: idRec
  }, function(err) {
    if (err) console.log(err);
  });
};

Trader.prototype.reportEvent = function reportEvent(eventType, note) {
  var rec = {
    eventType: eventType,
    note: note,
    deviceTime: Date.now()
  };
  this._request({
    path: '/event',
    method: 'POST',
    body: rec,
    repeatUntilSuccess: true
  }, function (err) {
    if (err) console.log(err);
  });
};

Trader.prototype.sendBitcoins = function sendBitcoins(tx, cb) {
  tx.sequenceNumber = ++sequenceNumber;
  this._request({
    path: '/send',
    method: 'POST',
    body: tx,
    repeatUntilSuccess: true
  }, function (err, result) {
    if (!err) cb(null, result.txHash);
    else {
      if (err.name === 'InsufficientFunds') return cb(err);
      if (err.name === 'networkDown') return cb(new Error('sendBitcoins timeout'));
    }
  });

  sequenceNumber = 0;
};

Trader.prototype.trigger = function trigger() {
  var self = this;

  // Not paired yet<commit_msg>backwards compat with l-s@1.0.2<commit_after>'use strict';

var fs = require('fs');
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var async = require('async');
var uuid = require('node-uuid');

var jsonquest = require('./jsonquest');

var _t0 = null;
var sequenceNumber = 0;

var Trader = function(config) {
  if (!(this instanceof Trader)) return new Trader(config);
  EventEmitter.call(this);

  this.connectionInfo = null;
  this.protocol = config.protocol || 'https';
  this.rejectUnauthorized = typeof config.rejectUnauthorized === 'undefined' ?
    true :
    !!config.rejectUnauthorized;

  this.config = config;
  this.exchangeRate = null;
  this.fiatExchangeRate = null;
  this.balance = null;
  this.locale = null;

  this.exchange = null;
  this.balanceTimer = null;
  this.balanceRetries = 0;
  this.balanceTriggers = null;
  this.tickerExchange = null;
  this.transferExchange = null;
  this.pollTimer = null;
  this.pollRetries = 0;
  this.txLimit = null;
  this.fiatTxLimit = 50;  // TODO: make configurable
  this.idVerificationLimit = null;
  this.idVerificationEnabled = false;
  this.sessionId = null;
  this.twoWayMode = false;
};
util.inherits(Trader, EventEmitter);

Trader.prototype.init = function init(connectionInfo) {
  if (this.protocol === 'https') {
    this.cert = fs.readFileSync(this.config.certs.certFile);
    this.key = fs.readFileSync(this.config.certs.keyFile);
  }
  this.connectionInfo = connectionInfo;

  jsonquest.setEmitter(this.emit);
};

Trader.prototype.pair = function pair(connectionInfo) {
  this.connectionInfo = connectionInfo;
};

Trader.prototype._request = function _request(options, cb) {
  var protocol = this.protocol || 'https';
  var connectionInfo = this.connectionInfo;
  var host = protocol === 'http' ? 'localhost' : connectionInfo.host;
  var fingerprint = protocol === 'http' ? false : connectionInfo.fingerprint;
  var self = this;
  var sessionId = this.sessionId;
  var headers = sessionId ? {'session-id': sessionId} : {};
  if (options.body) headers['content-type'] = 'application/json';

  jsonquest({
    protocol: protocol,
    host: host,
    port: connectionInfo.port,
    cert: this.cert,
    key: this.key,
    rejectUnauthorized: this.rejectUnauthorized,
    method: options.method,
    path: options.path,
    body: options.body,
    headers: headers,
    fingerprint: fingerprint,
    repeatUntilSuccess: options.repeatUntilSuccess
  }, function (err, res, body) {
    if (sessionId && sessionId !== self.sessionId) {
      console.log('WARN: received a response from old sessionId: %s, ' +
        'current is: %s', sessionId, self.sessionId);
      return; // No need to call handler
    }

    if (err) return cb(_richError(err.message, 'networkDown'));

    if (res.statusCode === 404) {
      self.connectionInfo = null;
      return cb(_richError('Server has unpaired', 'unpair'));
    }

    // All 2xx codes are OK
    if (res.statusCode < 200 || res.statusCode >= 300)
      return cb(_richError('Server returned ' + res.statusCode + ': ' + body.err));

    var errRec = body.err ? {name: body.errType, message: body.err} : null;
    var result = body;

    if (errRec) return cb(_richError(errRec.message, errRec.name));
    cb(null, result);
  });
};

Trader.prototype.run = function run() {
  var self = this;

  self.trigger();
  self.triggerInterval = setInterval(function() {
    self.trigger();
  }, this.config.settings.pollInterval);
};

Trader.prototype.stop = function stop() {
  if (this.triggerInterval) clearInterval(this.triggerInterval);
};

Trader.prototype.verifyUser = function verifyUser(idRec, cb) {
  console.log(idRec);
  this._request({
    path: '/verify_user',
    method: 'POST',
    body: idRec
  }, cb);
};

Trader.prototype.verifyTransaction = function verifyTransaction(idRec) {
  console.log(idRec);
  this._request({
    path: '/verify_transaction',
    method: 'POST',
    body: idRec
  }, function(err) {
    if (err) console.log(err);
  });
};

Trader.prototype.reportEvent = function reportEvent(eventType, note) {
  var rec = {
    eventType: eventType,
    note: note,
    deviceTime: Date.now()
  };
  this._request({
    path: '/event',
    method: 'POST',
    body: rec,
    repeatUntilSuccess: true
  }, function (err) {
    if (err) console.log(err);
  });
};

Trader.prototype.sendBitcoins = function sendBitcoins(tx, cb) {
  tx.sequenceNumber = ++sequenceNumber;

  // For backwards compatibility with lamassu-server@1.0.2
  tx.txId = uuid.v4();

  this._request({
    path: '/send',
    method: 'POST',
    body: tx,
    repeatUntilSuccess: true
  }, function (err, result) {
    if (!err) cb(null, result.txHash);
    else {
      if (err.name === 'InsufficientFunds') return cb(err);
      if (err.name === 'networkDown') return cb(new Error('sendBitcoins timeout'));
    }
  });

  sequenceNumber = 0;
};

Trader.prototype.trigger = function trigger() {
  var self = this;

  // Not paired yet
{'fraction_non_alphanumeric': 0.14281339322172315, 'fraction_numerical': 0.004185381788485096, 'mean_word_length': 3.6365357311878843, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7505712', 'n_tokens_mistral': 3173, 'n_tokens_neox': 3091, 'n_words': 734}