/*****************************************************/
/*          ENTER your network parameters            */
var APN = "";
var USERNAME = "";
var PASSWORD = "";

var CLOUD_PROVIDER = "www.grovestreams.com";
var API_KEY = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";

/******************************************************

/******************************************************
 * Demo on BRISK L496
 * + C2C board
 *
 * Demo :
 *  Power on the modem  
 *  Drive the modem
 *  Connect to cellular network for packet domain
 *  Access to a cloud and push (HTTP PUT)
 *
 * Usage:
 * Load the code to espruino, then, start modem
 *  > QuectelStart() ( or QuectelStart(true) )
 * When you get an IP address, the script will periodically
 * send information to cloud ( See sendCloud() )
 ******************************************************/


var gprs;

// memory tracking 
var initFreeMem = process.memory().free;
var maxFreeMem = process.memory().free;
var minFreeMem = process.memory().free;

// 16 bytes is the standard block size, this can be 12 on very constrained platforms
console.log("minFreeMem is now: " + minFreeMem*16 + " bytes");
console.log("maxFreeMem is now: " + maxFreeMem*16 + " bytes");

function SimSelect() {
  // SELECTING SIM (external slot)
  digitalWrite("A2",0);    //IO18, SIM select 0
  digitalWrite("C8",0);    //IO18
  digitalWrite("G10",0);   //IO18

  digitalWrite("A7",0);    //I08, SIM select 1
  digitalWrite("D10",0);   //IO8

  // SELECTING SIM (embedded SIM)
  //digitalWrite("A2",1);    //IO18, SIM select 0
  //digitalWrite("C8",1);    //IO18
  //digitalWrite("G10",1);   //IO18

  //digitalWrite("A7",0);    //I08, SIM select 1
  //digitalWrite("D10",0);   //IO8
}

function QuectelStart(debug_quectel, debug_at) {
  // input parameters init
  debug_quectel = debug_quectel || false;
  debug_at = debug_at || false;

  // HW pins (RTS, CTS) setup
  pinMode(D11, "input", true);
  pinMode(D12, "output", true);

  // UART set-up
  // with flow control setup, receive only, managed by SW, MCU side, espruino level
  Serial3.setup(115200, { rx: D9, tx : D8, cts: D12 });

  SimSelect();
  // Connect to modem 
  console.log("Connecting to NW with Quectel UGxx module ... this may take few minutes");
  resetOptions = {
   rst: "A8",
   pwrkey: "A6",
   rst_active_level: 1,
   pwrkey_active_level: 0,
  };
  gprs = require('QUECTEL').connect(Serial3, resetOptions, function(err) {
    console.log("connectCB entered...");
    if (err) throw err;
    whoAmI();
  });
  // Move debug parameters to true to get Quectel/AT debug logs
  gprs.debug(debug_quectel, debug_at);
}

/* Modem info (model, version) */
function whoAmI(){
  if (gprs.at.isBusy()){
    console.log("at module still busy...waiting for 10sec...");
    setTimeout(function cb(){console.log("let's go ahead..."); whoAmI();}, 10000);
  } else {
    // modem info
    gprs.at.cmd("ATI\r\n", 30000, function cb2(d2) {
      if (d2===undefined) {console.log("...timeout...");return;}
      if (d2==='+CME ERROR: 4') {/* dust */return;}
      if (d2==='OK') {console.log(d2);return;}
      else {console.log("Modem: \n" + d2); return cb2;}
    });
    setTimeout(doConnect,30000);
  }
}

/* Trigger PDP context activation (can be required to set the APN the first time you use the Emnify SIM card) */
function doConnect() {
  gprs.connect(APN, USERNAME, PASSWORD, function(err) {
    console.log("gprs.connectCB entered...");
    if (err) throw err;
    onConnected();
  });
}


function onConnected (){ 
    gprs.getIP(print);

    setInterval(function() {
       sendCloud("Brisk2Cloud", "RandomValue", getRandomArbitrary(0, 20));
    }, 60000);
}


function sendCloud(compId, streamId, data) {
  var http = require("http");
  var packet = [ { "compId": compId, "streamId": streamId,"data": data }];

  var body=JSON.stringify(packet);
  
  memoryTracking();
  
  options = {
    host: CLOUD_PROVIDER,
      port: '80',
      path: "/api/feed?api-key="+API_KEY,
      method:'POST',      
      headers: { "Connection": "close","Content-Type":"application/json", 
                "Content-Length": body.length,
                "Cookie": "api_key="+API_KEY}
  };
  //print(options);
  print(body);
  console.log("================================");
  //print(options);
  //print(body);
 
   var req = require("http").request(options, function(res)  {
    res.on('data', function(data) {
      console.log("-->"+data);
    });
    res.on('close', function(data) {
      console.log("==> Closed.");
    });
  });
  req.end(body);
}



/**
 * Returns a random number between min (inclusive) and max (exclusive)
 */
function getRandomArbitrary(min, max) {
    return Math.random() * (max - min) + min;
}


function memoryTracking() {
        var BlockSize = 16;
        var vFreeMem = process.memory().free;
        
        if (vFreeMem < minFreeMem) {
                minFreeMem = vFreeMem;
                console.log("minFreeMem is now: " + minFreeMem*BlockSize + " bytes");
        } else if (vFreeMem > maxFreeMem) {
                maxFreeMem = vFreeMem;
                console.log("maxFreeMem is now: " + maxFreeMem*BlockSize + " bytes");
        } 
}

setTimeout(QuectelStart, 100);
