var fs = require("fs");
var path = require('path');
var parent_dir = process.getAbsolutePath(__dirname);
var check = require("check-types");
var _ = require("underscore");
/**
Represents configuration.
@constructor
@param {Message} message_obj
@author Tilak Patidar <tilakpatidar@gmail.com>
*/
var Config = function(message_obj) {
var that = this;
var message = message_obj;
var proto = require(parent_dir + '/lib/proto.js');
var JSONX = proto.JSONX;
var ObjectX = proto.ObjectX;
var pool;
var OVERRIDEN_CONFIG = {};
var DB_CONFIG = {};
var log = message.get('log');
/**
Sets the db object.
@public
@param {MongoDB} p
*/
this.setDB = function setDB() {
pool = message.get('pool');
};
/**
Stores config.
@private
@type Object
*/
if (process.RUN_ENV === "TEST") {
var config = {
"verbose": false,
"logging": false
}; //by default will get overidden once config is loaded from db
} else {
var config = {
"verbose": true,
"logging": true
}; //by default will get overidden once config is loaded from db
}
/**
Overrides the db and local config with command line arguments.
Writes the overriden config to disk.
Reloades config for current instance.
@public
@params {Object} dic - Parsed command line args
*/
this.setOverridenConfig = function override(dic) {
_.each(dic, function(v, k) {
msg("Overriden config " + k + " for value " + dic[k], "info");
});
if (!check.assigned(dic)) {
//if undefined reload config from disk
var data;
try {
data = fs.readFileSync(parent_dir + '/config/config_override.json').toString();
} catch (err) {
var stream = fs.createWriteStream(parent_dir + "/config/config_override.json");
stream.write("{}");
stream.end();
data = "{}"; //JSON parse below
}
if (data === "") {
data = "{}";
}
OVERRIDEN_CONFIG = JSON.parse(data);
} else {
OVERRIDEN_CONFIG = dic;
try {
fs.writeFileSync(parent_dir + '/config/config_override.json', JSON.stringify(dic));
} catch (err) {
var stream = fs.createWriteStream(parent_dir + "/config/config_override.json");
stream.write("{}");
stream.end();
}
}
};
/**
Adds db config from db_config.json to config var.
@private
@param {Object} dic - db config
*/
function setDbConfig(dic) {
if (!check.assigned(dic)) {
//if undefined reload config from disk
var data;
try {
data = fs.readFileSync(parent_dir + '/config/db_config.json').toString();
} catch (err) {
var stream = fs.createWriteStream(parent_dir + "/config/db_config.json");
stream.write("{}");
stream.end();
stream.on("finish", function() {
console.log("db config for bot is not set.\nSet using bot-marvin-db");
message.set("stop_bot_and_exit");
});
return;
}
try {
DB_CONFIG = JSON.parse(data);
//console.log(DB_CONFIG);
//file present with no json in it
} catch (err) {
var stream = fs.createWriteStream(parent_dir + "/config/db_config.json");
stream.write("{}");
stream.end();
stream.on("finish", function() {
console.log("db config for bot is not set.\nSet using bot-marvin-db");
message.set("stop_bot_and_exit");
});
return;
}
} else {
DB_CONFIG = dic;
try {
fs.writeFileSync(parent_dir + '/config/db_config.json', JSON.stringify(dic));
} catch (err) {
var stream = fs.createWriteStream(parent_dir + "/config/db_config.json");
stream.write("{}");
stream.end();
stream.on("finish", function() {
console.log("db config for bot is not set.\nSet using bot-marvin-db");
message.set("stop_bot_and_exit");
});
return;
}
}
}
/**
Updates the config in the db for current bot.
@param {Object} dic - config
@param {Function} fn - callback
@public
*/
this.updateDbConfig = function updateDbConfig(dic, fn) {
pool.stats.updateConfig(that.getConfig('bot_name'), dic, function updateDbConfig_updateConfig(err, results) {
var jsonx_str = new JSONX(dic);
config = JSONX.parse(jsonx_str.stringify()); //update config var so that on bot close changes will appear
return fn(err, results);
});
//updates the config changes done from local machine to db
}
/**
Fetches latest config copy from db.
@public
@param {Function} fn - callback
*/
this.getConfigFromDb = function pullDbConfig(fn) {
pool.config_reloader.pullDbConfig(that.getConfig('bot_name'), function pullDbConfig_pullDbConfig(err, results) {
return fn(err, results);
});
};
/**
Returns the config value for asked keys.
@public
*/
this.getConfig = function getConfig() {
//console.log(DB_CONFIG,"WHEN called");
var val = config;
if (!check.assigned(arguments[0])) {
return config;
}
for (var i = 0; i < arguments.length; i++) {
if (check.assigned(OVERRIDEN_CONFIG[arguments[i]])) {
val = OVERRIDEN_CONFIG[arguments[i]]; //overrides the config with command line arguments
} else if (check.assigned(DB_CONFIG[arguments[i]])) {
val = DB_CONFIG[arguments[i]];
} else {
val = val[arguments[i]];
}
};
return val;
};
/**
Returns globals so that new config object can be created on spawned process.
@public
*/
this.getGlobals = function getGlobals() {
var jsonx_obj = new JSONX(config);
return [JSON.parse(jsonx_obj.stringify()), OVERRIDEN_CONFIG, DB_CONFIG];
};
/**
This pulls config from db and if config is not set display warning and stops bot.
@param {Function} fn - callback
*/
this.pullConfig = function pullConfig(fn) {
that.getConfigFromDb(function pullDbConfig(err, results) {
if (check.emptyObject(results) || !check.assigned(results)) {
if (!message.get('modifyConfig')) {
console.log("You have to set your bot config.\nRun bot-marvin --config\nRun bot-marvin --load-config <filename>");
message.set('stop_bot_and_exit');
return fn(null);
} else {
return fn(null);
}
} else {
config = JSONX.parse(JSON.stringify(results));
return fn(config);
}
});
};
/**
This function is called in an interval to fetch and compare config. If config is changed from db it restart the bot.
*/
function configReloader() {
that.getConfigFromDb(function configReloader_pullDbConfig(err, new_config) {
//console.log(new_config)
if (check.assigned(new_config)) {
//console.log(new_config);
//console.log(JSON.parse(JSONX.stringify(gc())));
var jsonx_obj = new JSONX(that.getConfig());
if (!ObjectX.isEquivalent(new_config, JSON.parse(jsonx_obj.stringify()))) {
msg("Config changed from db ", "info");
//if local and db copy unmatches
//means config has been changed from db
message.set("restart");
} else {
msg("No change in config", "info");
}
}
});
};
var config_check_mode = setInterval(function() {
var b = setInterval(function() {
if (message.get('begin_intervals')) {
configReloader();
}
}, 10000);
message.get('my_timers').push(b);
clearInterval(config_check_mode); //once intervals are set clear the main interval
}, 5000);
this.setOverridenConfig(); //run for first time
setDbConfig();
/**
Used to call Logger object with the caller function name.
@private
*/
function msg() {
if (!check.assigned(message.get('log'))) {
console.log(arguments[0]);
return;
}
message.get('log').put(arguments[0], arguments[1], __filename.split('/').pop(), arguments.callee.caller.name.toString());
}
};
module.exports = Config;