"use-strict"
var rpc = require("json_rpc");
var http = require("http");
var Message = require("message.js").Message;
var messages = require("data.js");
var Config = require("config.js");

var HttpClient = http.HttpClient;
var HttpSession = http.HttpSession;
var HttpRequest = http.HttpRequest;
var HttpResponse = http.HttpResponse;

var messageID = 0;
var parser = require("xml-parser");

if (Config.tlsEnabled) {
  http.ssl.registerClientContext(
    Config.tlsPrivateKey,
    function(){console.log("Password Verification")}, 
    Config.tlsCertificate,
    function(cert)
    {
      console.log("CLIENT", JSON.stringify(cert));
      return true;
    },
    Config.tlsCaLocation,
    Config.tlsVerificationMode
  );
}

var sender = new rpc.JsonRpcClient(new rpc.JsonRpcHttpClient(Config.pushNotificationRpcHost, Config.pushNotificationRpcPort, Config.tlsEnabled));

var validate_object = function(obj) {
  return !(!obj ||
         !obj.Operation ||
         !obj.Operation.SubmitRequest ||
         !obj.Operation.SubmitRequest.SubmitHeader ||
         !obj.Operation.SubmitRequest.SubmitHeader.Originator ||
         !obj.Operation.SubmitRequest.SubmitHeader.MessageControl ||
         !obj.Operation.SubmitRequest.SubmitHeader.Recipient ||
         !obj.Operation.SubmitRequest.Payload ||
         !obj.Operation.SubmitRequest.Payload.Alphanumeric);

}

var push_notification = function(address, number)
{
  var obj = null;
   console.log("push_notification - INVOKED for " + number + "@" + address);
   try {
   console.log("parsing randome message for " + number + "@" + address);
   var message = messages.getRandomMessage();
   
   console.log("parsing WCTP message " + message);
   obj = parser.parse(message, {
          ignoreTextNodeAttr : false,
          attrNodeName:"attribute",
          attrPrefix:"",
          textAttrConversion : false
    });
  } catch( e ) {
    console.log("Caught exception " + e);
  }

  if (validate_object(obj)) {
	  var date = new Date(Date.now());
	  obj.Operation.timeStamp = date.toISOString();
    
    
    obj.Operation.SubmitRequest.SubmitHeader.Originator.attribute.senderAddress = address;
	  obj.Operation.SubmitRequest.SubmitHeader.MessageControl.attribute.messageID = Date.now().toString() + "-" + (++messageID).toString();
	  obj.Operation.SubmitRequest.SubmitHeader.Recipient.attribute.recipientID = number;
	  var msg = new Message(obj.Operation.SubmitRequest.Payload.Alphanumeric);
	  obj.Operation.SubmitRequest.Category = msg.category;
	  obj.Operation.SubmitRequest.Text = msg.text;
    console.log(JSON.stringify(obj));
	  sender.execute("/notify/", "receive", obj, function(response)
	  {
	    console.log(response.toJSON(null, 2));
	    console.log("Next send set to fire after " + (Config.pushFrequency / 1000) + " seconds");
	  });
  } else {
    console.log("Invalid Object " + JSON.stringify(obj) + ".\n  Next send set to fire after " + (Config.pushFrequency / 1000) + " seconds");
  }
  async.setTimeout(on_timer, Config.pushFrequency, ["Hello Timers!", new Date()]);
}

var on_timer = function(msg, start)
{
  var device = getNextDevice();
  push_notification(device.emergin_gateway, device.phone_number);
}

var deviceIndex = 0;
var totalDevices = 0;

var getNextDevice = function() {
  var device = Config.deviceMap[deviceIndex++];
  if (deviceIndex >= totalDevices) {
    deviceIndex = 0;
  }
  return device;
}

var deviceMapClient = new HttpClient(Config.deviceMapTls);
deviceMapClient.setHost(Config.deviceMapHost);
deviceMapClient.setPort(Config.deviceMapPort);
var session = new HttpSession(deviceMapClient);


var buff = new Array();
var contentLength;
session.on("read", function(data) {
  if (data.length > 0) {
    buff = buff.concat(data);
    if (contentLength) {
      //
      // We are done.  We have a content length so we are sure we read the correct amount
      // Start the timer
      //
      Config.deviceMap = JSON.parse(utils.bufferToString(buff));
      totalDevices = Config.deviceMap.length;
      async.setTimeout(on_timer, 1000, ["Push Timer", new Date()]);
    } else {
      //
      // read some more since we dont know exactly how much data there is
      //
      session.read(1024);
    }
  } else {
    //
    // No more data left to read.  We are done.
    // Start the timer
    //
    Config.deviceMap = JSON.parse(utils.bufferToString(buff));
    totalDevices = Config.deviceMap.length;
    async.setTimeout(on_timer, 1000, ["Push Timer", new Date()]);
  }
});

session.on("error", function(message) {
    console.log(message);
    system.exit(-1);
  });

var request = new HttpRequest();
request.setVersion(http.HTTP_1_1);
request.setMethod(http.HTTP_GET);
request.setUri(Config.deviceMapUri);
request.setContentLength(0);

session.send(request, function(request) {
  session.receiveResponse(function(response) {
    contentLength = response.getContentLength();
    if (typeof contentLength === "number" && contentLength == -1) {
      contentLength = 0;
    }
    session.read(contentLength ? contentLength : 1024);
  });
});









