"use strict";

var fs = require ("fs");


var HubConfig = function(locations) {

	this.path = null;
	this.locations = locations;

	// Diaptoval defaults
	this.data = {};

	// Diaptoval Core namespace
	this.data.Core = {};
	this.data.Core.socket = "/tmp/diaptoval.sock";

	this.data.IRC = {};
	this.data.IRC.default = {};
	this.data.IRC.servers = [];
};


HubConfig.prototype.load = function(callback, self) {
	var locations, config = this;

	// Make a copy of the locations array
	locations = this.locations.slice ();
	
	// Continuation-passing style is the best
	(function retry() {

		if (!locations.length) {
			// We have no more locations to look
			console.error ("No configuration file found, using defaults");
			callback.call (self, config);
			return;
		}

		// Pop location off beginning of array
		var file = locations.shift ();

		config.load_file (file, function (success) {
			if (success) {
				config.path = file;
				callback.call (self, config);
			} else {
				retry ();
			}
		});

	})();

};


/**
 * HubConfig#load_file()
 * Read a Diaptoval configuration file into the object
 **/
HubConfig.prototype.load_file = function (filename, callback) {
	var self = this;

	fs.readFile(filename, "utf8", function (err, json) {
		var data;

		if (err) {
			callback.call (this, false);
			return;
		}

		console.log ("Reading configuration: %s", filename);

		try {
			// Try to parse the file as JSON
			data = JSON.parse (json);

			self.load_config_data (data);
			callback.call (this, true);
		} catch (e) {
			console.error (String(e));
			callback.call (this, false);
		}
	});
};

/**
 * HubConfig#write_file():
 * Save the configuration data as-is to disk.
 **/
HubConfig.prototype.write_file = function(file, callback) {
	var data, self = this;

	data = JSON.stringify (this.data, null, 4);

	if (!file) file = this.path;
	if (!file) throw new Error ("No place to save configuration");

	fs.writeFile(file, data, 'utf8', function(err) {
		var success = !err;
		callback.call (self, success);
	});
};

HubConfig.prototype.load_config_data = function (data) {

	// Iterate and copy over the object recursively
	(function extend (base, extension) {
		for (var prop in extension) {
			if (extension.hasOwnProperty (prop)) {
				if (typeof base[prop] === "object") {
					if (typeof extension[prop] === "object") {
						extend (base[prop], extension[prop]);
					} else {
						throw new Error ("A "+(typeof extension[prop])+" exists where an object is expected");
					}
				} else {
					base[prop] = extension[prop];
				}
			}
		}
	}) (this.data, data);
};


module.exports = HubConfig;

@@ -2016,16 +2016,17 @@
 %7D);%0A%7D;%0A%0A
+%0A
 HubConfi
@@ -2079,173 +2079,145 @@
  %7B%0A%0A
-%09// Iterate and copy over the object recursively%0A%09(function extend (base, extension) %7B%0A%09%09for (var prop in extension) %7B%0A%09%09%09if (extension.hasOwnProperty
+    var getOwn = Object.getOwnPropertyNames;%0A%0A    (function extend (base, extension) %7B%0A%09getOwn(extension).forEach(function
  (prop)
-)
  %7B%0A%09
-%09%09%09
+    
 if (
@@ -2238,31 +2238,28 @@
 op%5D === 
-%22
+'
 object
-%22
+'
 ) %7B%0A
-%09%09%09
 %09%09if (ty
@@ -2283,88 +2283,30 @@
 op%5D 
-=== %22
+!== '
 object
-%22
+'
 ) %7B%0A%09%09
-%09%09%09%09extend (base%5Bprop%5D, extension%5Bprop%5D);%0A%09%09%09%09%09%7D else %7B%0A%09%09%09%09%09%09
+    
 thro
@@ -2320,16 +2320,16 @@
 rror
- (%22A %22+(
+('A ' + 
 type
@@ -2350,11 +2350,21 @@
 rop%5D
-)+%22
+ + %0A%09%09%09%09    '
  exi
@@ -2398,32 +2398,75 @@
 cted
-%22
+.'
 );%0A%09%09
-%09%09%09%7D%0A%09%09%09%09%7D
+%7D%0A%09%09extend(base%5Bprop%5D, extension%5Bprop%5D);%0A%09    %7D%0A%09   
  else %7B%0A
 %09%09%09%09
@@ -2461,19 +2461,16 @@
  else %7B%0A
-%09%09%09
 %09%09base%5Bp
@@ -2498,26 +2498,25 @@
 %5D;%0A%09
-%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%09
+    %7D%0A%09%7D);%0A    
 %7D)
- 
 (thi

Refactor HubConfig.prototype.load_config_data.