'use strict';

var request = require('request');
var r = require('rethinkdb');
var Promise = require('es6-promise').Promise;
var _ = require('lodash');

var Aggregator = function Aggregator(options) {
    var self = this;

    this.parseJSON = function parseJSON(body) {
        var data;
        try {
            data = JSON.parse(body);
        } catch (e) {
            return Promise.reject(e);
        }
        return Promise.resolve(data);
    };

    this.writeJSON = function (json) {
        return r.db(self.dbConfig.db)
            .table('currentNetwork')
            .replace(json, { returnChanges: false })
            .run(self.connection);
    };

    this.finish = function finish(res) {
        if (self.connection && self.connection.open) {
            self.connection.close();
        }
        return res;
    };

    _.merge(this, options);

    this.aggregate = function aggregate(backend, dbConfig) {
        self.dbConfig = dbConfig || self.dbConfig;
        return r.connect(dbConfig).then(function (c) {
            self.connection = c;
            return Promise.all(backend.endpoints.map(function (id) {
                return self.fetchData(backend.base + '/' + id)
                    .then(self.parseJSON)
                    .then(function addMetaDataData(json) {
                        json.id = id;
                        if (!json.timestamp) {
                            json.timestamp = new Date().toISOString();
                        }
                        return json;
                    })
                    .then(self.writeJSON);
            }));
        }).then(self.finish);
    };
};

var api = {};

api.remote = new Aggregator({
    fetchData: function (path) {
        return new Promise(function (resolve, reject) {
            request(path, function (err, res, body) {
                if (err) {
                    reject(err);
                } else {
                    resolve(body);
                }
            });
        });
    }
});

api.local = new Aggregator({
    fetchData: function (path) {
        var fs = require('fs');

        return new Promise(function (resolve, reject) {
            fs.readFile(path, function (err, content) {
                if (err) {
                    reject(err);
                } else {
                    resolve(content);
                }
            });
        });
    }
});

module.exports = {
    for: function (type) {
        return api[type];
    }
};

@@ -441,32 +441,829 @@
 (data);%0A    %7D;%0A%0A
+    this.normalize = function normalize(json) %7B%0A        if (json.nodes) %7B%0A            json.nodes = json.nodes.map(function (node) %7B%0A                node.nodeinfo = node.nodeinfo %7C%7C %7B%7D;%0A                if (_.isArray(node.geo) && node.geo.length === 2) %7B%0A                    node.nodeinfo.location = %7B%0A                        latitude: node.geo%5B0%5D,%0A                        longitude: node.geo%5B1%5D%0A                    %7D;%0A                    delete node.geo;%0A                %7D%0A                if (node.firmware) %7B%0A                    node.nodeinfo.software = node.nodeinfo.software %7C%7C %7B%0A                        firmware: node.firmware%0A                    %7D;%0A                    delete node.firmware;%0A                %7D%0A                return node;%0A            %7D);%0A        %7D%0A        return json;%0A    %7D;%0A%0A
     this.writeJS
@@ -2327,24 +2327,66 @@
          %7D)%0A
+                    .then(self.normalize)%0A
             

add a normalize step to aggregation