#require "Firebase.class.nut:1.1.1"

///////// Application Code ///////////

// VARIABLES
agentID <- split(http.agenturl(), "/").pop();

// INITIALIZE CLASSES
const FIREBASENAME = "<--YOUR FIREBASE NAME-->";
const FIREBASESECRET = "<--YOUR FIREBASE SECRET KEY-->";

fb <- Firebase(FIREBASENAME, FIREBASESECRET);

// APPLICATION FUNCTIONS

// Save settings to local storage
function saveSettings(settings) {
    server.save({ "settings" : settings });
}

// Check local storage for settings and sync with device
function getSettings(dummy) {
    local persist = server.load();

    // If no settings request from device
    if (!("settings" in persist)) { device.send("getDeviceSettings", null); }
    
    // If have settings send to device
    if ("settings" in persist) { device.send("agentSettings", persist.settings); }
}

// Overwrite default reading/reporting interval settings is a table 
function updateSettings(settings) {
    local persist = server.load();
    if ("settings" in persist) {
        if ( !("readingInt" in settings) ) {
            settings.readingInt <- persist.settings.readingInt;
        }
        if ( !("reportingInt" in settings) ) {
            settings.reportingInt <- persist.settings.reportingInt;
        }
    }
    saveSettings(settings);
    device.send("agentSettings", settings);
}

// Store data to Firebase
function storeData(data) {
    foreach(sensor, readings in data) {
        server.log(sensor + " " + http.jsonencode(readings));
        buildQue(sensor, readings, writeQueToFB)
    }
    device.send("ack", "OK");
}

// Sort readings by timestamp
function buildQue(sensor, readings, callback) {
    readings.sort(function (a, b) { return b.ts <=> a.ts });
    callback(sensor, readings);
}

// Loop that writes readings to db in order by timestamp
function writeQueToFB(sensor, que) {
    if (que.len() > 0) {
        local reading = que.pop();
        fb.push("/data/"+agentID+"/"+sensor, reading, null, function(res) { writeQueToFB(sensor, que); }.bindenv(this));
    }
}

// DEVICE LISTENERS
device.on("deviceSettings", saveSettings);
device.on("getAgentSettings", getSettings);
device.on("data", storeData);

// Uncomment lines below if you want to update reading, reporting intervals
// local newSettings = {"reportingInt" : 600};
// updateSettings(newSettings);