<commit_before>/*
 * ejabberd
 * https://github.com/Wiredcraft/ejabberd
 *
 * Copyright (c) 2012 wiredcraft
 * Licensed under the MIT license.
 */

var fs = require('fs');
var path = require('path');
var util = require('util');
var EventEmitter = require('events').EventEmitter;

// Defaults
const STOP_TIME = 1000 * 3; // ms
const PAUSE_TIME = 1000 * 0.5; // ms
const RESTART_TIME = 1000 * 8; // ms
const CHECKER_INTERVAL = 500; // ms
const EMPTY_DB = {hosts:[], configs:[]};
const ADAPTERS = require('../adapters');
const DEBUG = process.env.NODE_ENV === 'development' ? true : false;
const PACKAGE = require('../package.json');
const TEMPL_DIR = path.resolve(__dirname, '../templates');

var which = require('which');
var Q = require('q');
var _ = require('underscore');

var db = require('./db');
var config = require('./config');
var control = require('./control');

var logger = require('./helpers').logger;
var sortArgs = require('./helpers').sortArgs;
var ensureExt = require('./helpers').ensureExt;

// Ejabberd class
var Ejabberd = function(dist, options) {

  options = options || {};
  dist = dist || process.env.EJABBERD_DIST;

  if (!dist) {
    throw new Error('Arguments Error: You need to specify the os distribution, e.g ubuntu/osx ...');
  }

  if (!ADAPTERS[dist] && !options.dist) {
    throw new Error('Key Error: The dist name ' + dist+ ' not found in existing adapters');
  } else {
    this.dist = ADAPTERS[dist] || options.dist;
  }

  // .
  this.version = PACKAGE.version;

  return this.initialize(dist, options);
};

// Make Ejabberd instance a event emitter
util.inherits(Ejabberd, EventEmitter);

// .
Ejabberd.prototype.initialize = function(dist, options) {
  var ejabberd = this;
  var cfgTemplFile = path.resolve(TEMPL_DIR, dist, 'ejabberd.cfg.ejs');
  var vhostsTemplFile = path.resolve(TEMPL_DIR, dist, 'vhosts.cfg.ejs');
  var vhostConfigTemplFile = path.resolve(TEMPL_DIR, dist, 'vhost.cfg.ejs');

  ejabberd.ctl = ejabberd.dist.ctl || which.sync('ejabberdctl');
  fs.readFileSync(ejabberd.ctl);

  // FIXME: check existsness of config dir
  ejabberd.sudo = !!options.sudo;
  ejabberd.cfgDir = ejabberd.dist.cfgDir;
  ejabberd.incDir = path.resolve(ejabberd.cfgDir, 'includes');
  ejabberd.dbFile = path.resolve(ejabberd.cfgDir, 'database.json');
  ejabberd.stopTime = options.stopTime || STOP_TIME;
  ejabberd.pauseTime = options.pauseTime || PAUSE_TIME;
  ejabberd.restartTime = options.restartTime || RESTART_TIME;
  ejabberd.debug = options.debug || DEBUG;
  ejabberd.cfgTempl = fs.readFileSync(cfgTemplFile, 'utf-8');
  ejabberd.vhostsTempl = fs.readFileSync(vhostsTemplFile, 'utf-8');
  ejabberd.vhostConfigTempl = fs.readFileSync(vhostConfigTemplFile, 'utf-8');

  // .
  var markFile = path.resolve(ejabberd.incDir, 'mark.txt');
  var cfgFile = path.resolve(ejabberd.cfgDir, 'ejabberd.cfg');
  //var backupFile = path.resolve(ejabberd.cfgDir, 'ejabberd.cfg.backup');

  if (!fs.existsSync(ejabberd.incDir)) fs.mkdirSync(ejabberd.incDir);
  //if (!fs.existsSync(backupFile)) fs.linkSync(cfgFile, backupFile);

  // .
  // if (!fs.existsSync(ejabberd.dbFile)) {
  //   fs.writeFileSync(ejabberd.dbFile, JSON.stringify(EMPTY_DB), 'utf-8');
  //   ejabberd.db = EMPTY_DB;
  // } else {
  //   ejabberd.db = require(ejabberd.dbFile);
  // };

  fs.writeFileSync(markFile, 'MARK', 'utf-8');

  // Check status
  ejabberd.checker = setInterval(function() {
    ejabberd.ping().then(
      function() {  // Running
      ejabberd.running = true;

      if (ejabberd.debug) logger.info('Ejabberd is running.');

      ejabberd.emit('status', { running: true} );
    },
    function() {  // Down
      ejabberd.running = false;

      if (ejabberd.debug) logger.warn('Ejabberd is down.');

      ejabberd.emit('status', { running: false });
    }
    );
  }, options.checkerInterval || CHECKER_INTERVAL);

  return ejabberd;
};

Ejabberd.prototype.ping = function() {
  return control.status(this);
};

// .
Ejabberd.prototype.updateVhosts = function(data, host, cfg) {
  var ejabberd = this;
  var promises = [];
  var d = Q.defer();
  var db = {hosts:[], configs:[]};

  if (typeof data === 'string' || !data.length) {
    return Q.fcall(function() { throw new Error('Arguments error: data is not an array'); });
  };

  if (!ejabberd.running) {
    return Q.fcall(function() { throw new Error('Ejabberd server is not running'); });
  };

  // .
  data.forEach(function(host, index) {
    db['hosts'].push(host);
    db['configs'].push(path.resolve(ejabberd.incDir, host + '.cfg'));
  });

  db['hosts'] = _(db['hosts']).uniq();
  db['configs'] = _(db['configs']).uniq();

  // Here, order matters
  promises.push(config.updateVhostConfig(ejabberd, host, cfg));
  promises.push(config.updateConfig(ejabberd, db));
  promises.push(control.restart(ejabberd));

  Q.allResolved(promises).then(function(promises) {
    var success = 0;

    promises.forEach(function(p) {
      if (p.isFulfilled()) ++success;
    });

    if (success === promises.length) {
      d.resolve();
    } else {
      d.reject(new Error('Not all resolved'));
    }
  });

  return d.promise;
};

// .
Ejabberd.prototype.addVhost = function(data, target, cfg) {
  var ejabberd = this;
  var promises = [];
  var errMsg;
  var d = Q.defer();
  var db = {hosts:[], configs:[]};

  if (typeof data === 'string' || !data.length) {
    return Q.fcall(function() { throw new Error('Arguments error: data is not an array'); });
  };

  if (!(target && cfg)) {
    if (!target) {
      errMsg = 'missing host';
    } else {
      errMsg = 'missing vhost config';
    }

    return Q.fcall(function() { throw new Error('Arguments error: ' + errMsg); });
  }

  if (!ejabberd.running) {
    return Q.fcall(function() { throw new Error('Ejabberd server is not running'); });
  }

  var incFile = ensureExt(target, 'cfg');
  var incPath = path.resolve(ejabberd.incDir, incFile);

  // .
  data.forEach(function(host, index) {
    db['hosts'].push(host);
    db['configs'].push(path.resolve(ejabberd.incDir, host + '.cfg'));
  });

  // .
  db['hosts'].push(target);
  db['configs'].push(incPath);

  db['hosts'] = _(db['hosts']).uniq();
  db['configs'] = _(db['configs']).uniq();

  // Here, order matters
  promises.push(config.updateVhostConfig(ejabberd, target, cfg));
  promises.push(config.updateConfig(ejabberd, db));
  promises.push(control.restart(ejabberd));

  Q.allResolved(promises).then(function(promises) {
    var success = 0;

    promises.forEach(function(p) {
      if (p.isFulfilled()) ++success;
    });

    if (success === promises.length) {
      d.resolve();
    } else {
      d.reject(new Error('Not all resolved'));
    }
  });

  return d.promise;
};

Ejabberd.prototype.removeVhost = function(data, target, options) {
  var ejabberd = this;
  var promises = [];
  var errMsg;
  var d = Q.defer();
  var db = {hosts:[], configs:[]};

  if (typeof data === 'string' || !data.length) {
    return Q.fcall(function() { throw new Error('Arguments error: data is not an array'); });
  };

  if (!target) {
    errMsg = 'Arguments error: missing host';

    return Q.fcall(function() { throw new Error(errMsg); });
  }

  if (!ejabberd.running) {
    return Q.fcall(function() { throw new Error('Ejabberd server is not running'); });
  }

  var incFile = ensureExt(target, 'cfg');
  var incPath = path.resolve(ejabberd.incDir, incFile);

  // .
  data.forEach(function(host, index) {
    db['hosts'].push(host);
    db['configs'].push(path.resolve(ejabberd.incDir, host + '.cfg'));
  });<commit_msg>Use isArray from underscore<commit_after>/*
 * ejabberd
 * https://github.com/Wiredcraft/ejabberd
 *
 * Copyright (c) 2012 wiredcraft
 * Licensed under the MIT license.
 */

var fs = require('fs');
var path = require('path');
var util = require('util');
var EventEmitter = require('events').EventEmitter;

// Defaults
const STOP_TIME = 1000 * 3; // ms
const PAUSE_TIME = 1000 * 0.5; // ms
const RESTART_TIME = 1000 * 8; // ms
const CHECKER_INTERVAL = 500; // ms
const EMPTY_DB = {hosts:[], configs:[]};
const ADAPTERS = require('../adapters');
const DEBUG = process.env.NODE_ENV === 'development' ? true : false;
const PACKAGE = require('../package.json');
const TEMPL_DIR = path.resolve(__dirname, '../templates');

var which = require('which');
var Q = require('q');
var _ = require('underscore');

var db = require('./db');
var config = require('./config');
var control = require('./control');

var logger = require('./helpers').logger;
var sortArgs = require('./helpers').sortArgs;
var ensureExt = require('./helpers').ensureExt;

// Ejabberd class
var Ejabberd = function(dist, options) {

  options = options || {};
  dist = dist || process.env.EJABBERD_DIST;

  if (!dist) {
    throw new Error('Arguments Error: You need to specify the os distribution, e.g ubuntu/osx ...');
  }

  if (!ADAPTERS[dist] && !options.dist) {
    throw new Error('Key Error: The dist name ' + dist+ ' not found in existing adapters');
  } else {
    this.dist = ADAPTERS[dist] || options.dist;
  }

  // .
  this.version = PACKAGE.version;

  return this.initialize(dist, options);
};

// Make Ejabberd instance a event emitter
util.inherits(Ejabberd, EventEmitter);

// .
Ejabberd.prototype.initialize = function(dist, options) {
  var ejabberd = this;
  var cfgTemplFile = path.resolve(TEMPL_DIR, dist, 'ejabberd.cfg.ejs');
  var vhostsTemplFile = path.resolve(TEMPL_DIR, dist, 'vhosts.cfg.ejs');
  var vhostConfigTemplFile = path.resolve(TEMPL_DIR, dist, 'vhost.cfg.ejs');

  ejabberd.ctl = ejabberd.dist.ctl || which.sync('ejabberdctl');
  fs.readFileSync(ejabberd.ctl);

  // FIXME: check existsness of config dir
  ejabberd.sudo = !!options.sudo;
  ejabberd.cfgDir = ejabberd.dist.cfgDir;
  ejabberd.incDir = path.resolve(ejabberd.cfgDir, 'includes');
  ejabberd.dbFile = path.resolve(ejabberd.cfgDir, 'database.json');
  ejabberd.stopTime = options.stopTime || STOP_TIME;
  ejabberd.pauseTime = options.pauseTime || PAUSE_TIME;
  ejabberd.restartTime = options.restartTime || RESTART_TIME;
  ejabberd.debug = options.debug || DEBUG;
  ejabberd.cfgTempl = fs.readFileSync(cfgTemplFile, 'utf-8');
  ejabberd.vhostsTempl = fs.readFileSync(vhostsTemplFile, 'utf-8');
  ejabberd.vhostConfigTempl = fs.readFileSync(vhostConfigTemplFile, 'utf-8');

  // .
  var markFile = path.resolve(ejabberd.incDir, 'mark.txt');
  var cfgFile = path.resolve(ejabberd.cfgDir, 'ejabberd.cfg');
  //var backupFile = path.resolve(ejabberd.cfgDir, 'ejabberd.cfg.backup');

  if (!fs.existsSync(ejabberd.incDir)) fs.mkdirSync(ejabberd.incDir);
  //if (!fs.existsSync(backupFile)) fs.linkSync(cfgFile, backupFile);

  // .
  // if (!fs.existsSync(ejabberd.dbFile)) {
  //   fs.writeFileSync(ejabberd.dbFile, JSON.stringify(EMPTY_DB), 'utf-8');
  //   ejabberd.db = EMPTY_DB;
  // } else {
  //   ejabberd.db = require(ejabberd.dbFile);
  // };

  fs.writeFileSync(markFile, 'MARK', 'utf-8');

  // Check status
  ejabberd.checker = setInterval(function() {
    ejabberd.ping().then(
      function() {  // Running
      ejabberd.running = true;

      if (ejabberd.debug) logger.info('Ejabberd is running.');

      ejabberd.emit('status', { running: true} );
    },
    function() {  // Down
      ejabberd.running = false;

      if (ejabberd.debug) logger.warn('Ejabberd is down.');

      ejabberd.emit('status', { running: false });
    }
    );
  }, options.checkerInterval || CHECKER_INTERVAL);

  return ejabberd;
};

Ejabberd.prototype.ping = function() {
  return control.status(this);
};

// .
Ejabberd.prototype.updateVhosts = function(data, host, cfg) {
  var ejabberd = this;
  var promises = [];
  var d = Q.defer();
  var db = {hosts:[], configs:[]};

  if (typeof data === 'string' || !data.length) {
    return Q.fcall(function() { throw new Error('Arguments error: data is not an array'); });
  };

  if (!ejabberd.running) {
    return Q.fcall(function() { throw new Error('Ejabberd server is not running'); });
  };

  // .
  data.forEach(function(host, index) {
    db['hosts'].push(host);
    db['configs'].push(path.resolve(ejabberd.incDir, host + '.cfg'));
  });

  db['hosts'] = _(db['hosts']).uniq();
  db['configs'] = _(db['configs']).uniq();

  // Here, order matters
  promises.push(config.updateVhostConfig(ejabberd, host, cfg));
  promises.push(config.updateConfig(ejabberd, db));
  promises.push(control.restart(ejabberd));

  Q.allResolved(promises).then(function(promises) {
    var success = 0;

    promises.forEach(function(p) {
      if (p.isFulfilled()) ++success;
    });

    if (success === promises.length) {
      d.resolve();
    } else {
      d.reject(new Error('Not all resolved'));
    }
  });

  return d.promise;
};

// .
Ejabberd.prototype.addVhost = function(data, target, cfg) {
  var ejabberd = this;
  var promises = [];
  var errMsg;
  var d = Q.defer();
  var db = {hosts:[], configs:[]};

  if (!_(data).isArray()) {
    return Q.fcall(function() { throw new Error('Arguments error: data is not an array'); });
  };

  if (!(target && cfg)) {
    if (!target) {
      errMsg = 'missing host';
    } else {
      errMsg = 'missing vhost config';
    }

    return Q.fcall(function() { throw new Error('Arguments error: ' + errMsg); });
  }

  if (!ejabberd.running) {
    return Q.fcall(function() { throw new Error('Ejabberd server is not running'); });
  }

  var incFile = ensureExt(target, 'cfg');
  var incPath = path.resolve(ejabberd.incDir, incFile);

  // .
  data.forEach(function(host, index) {
    db['hosts'].push(host);
    db['configs'].push(path.resolve(ejabberd.incDir, host + '.cfg'));
  });

  // .
  db['hosts'].push(target);
  db['configs'].push(incPath);

  db['hosts'] = _(db['hosts']).uniq();
  db['configs'] = _(db['configs']).uniq();

  // Here, order matters
  promises.push(config.updateVhostConfig(ejabberd, target, cfg));
  promises.push(config.updateConfig(ejabberd, db));
  promises.push(control.restart(ejabberd));

  Q.allResolved(promises).then(function(promises) {
    var success = 0;

    promises.forEach(function(p) {
      if (p.isFulfilled()) ++success;
    });

    if (success === promises.length) {
      d.resolve();
    } else {
      d.reject(new Error('Not all resolved'));
    }
  });

  return d.promise;
};

Ejabberd.prototype.removeVhost = function(data, target, options) {
  var ejabberd = this;
  var promises = [];
  var errMsg;
  var d = Q.defer();
  var db = {hosts:[], configs:[]};

  if (!(!_(data).isArray()) {
    return Q.fcall(function() { throw new Error('Arguments error: data is not an array'); });
  };

  if (!target) {
    errMsg = 'Arguments error: missing host';

    return Q.fcall(function() { throw new Error(errMsg); });
  }

  if (!ejabberd.running) {
    return Q.fcall(function() { throw new Error('Ejabberd server is not running'); });
  }

  var incFile = ensureExt(target, 'cfg');
  var incPath = path.resolve(ejabberd.incDir, incFile);

  // .
  data.forEach(function(host, index) {
    db['hosts'].push(host);
    db['configs'].push(path.resolve(ejabberd.incDir, host + '.cfg'));
  });
{'fraction_non_alphanumeric': 0.1764784230154502, 'fraction_numerical': 0.003995737879595098, 'mean_word_length': 3.623460591133005, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, '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': '179108', 'n_tokens_mistral': 5495, 'n_tokens_neox': 5306, 'n_words': 1087}