/**
 * Created by TalhaAkkas on 24/06/15.
 */

exports.trackAllRequests = function(s){
	//s.createEventData = exports.createEventData
	//s.encapsulateFunction = exports.encapsulateFunction   // need function that encapsulated to have first arg as req and second arg as res
	for(var key in s){
		var obj = s[key];
		if(key != 'loadRelatedData' && typeof obj == "function"){
			var params = getParamNames(obj);
			if(params[0] == "req" && params[1] == "res" && params.length == 2){
				exports.encapsulateFunction(key, s);
			}
		}
	} 
};
exports.encapsulateFunction = function(funcNm, child) { // last argument must be callback; and must be different from loadRelatedData data
	//EWLog(child.pluralName, funcNm)
	child[funcNm] = child[funcNm].goAOP()
	child[funcNm].preCall = function(req, res){
		exports.createEventData(req, res, funcNm, child.pluralName)

        var argsPre = arguments.toArrayEW();
        var next = argsPre[argsPre.length -1];
        next.apply(this,argsPre);
	}
	/*var func = this[funcNm];
	var superNm = "__" + funcNm;
	var args = getParamNames(func);

	this[superNm] = func;


	var functionBody = "var args = [];";
	args.forEach(function(arg){ functionBody += "args.push(" + arg + ");\n" });
	functionBody += "arguments.callee.controller.createEventData(req,res,'"+funcNm+"', '" + this.pluralName +"')\n;";
	functionBody += "arguments.callee.controller['" + superNm + "'].apply(this, args)\n;";
	args.push(functionBody);
	this[funcNm] = construct(Function,  args);
	this[funcNm].controller = this;*/
};
exports.createEventData = function(request,response, functionType, classType){
	var mongoose = rekuire('mongoose');
	try{
		mongoose.model('EventLog')
	}catch(e){
		require("./EventLog");
	}
	var EventLog = mongoose.model('EventLog');
	var rawData = {}; 
	rawData.sessionID = request.sessionID;
	rawData.fulpath = request.protocol + '://' + request.get('host') + request.originalUrl;
	rawData.isMobile = request.isMobile;
	rawData.body = request.body;
	rawData.startTime = request.startTime;
	rawData.now = new Date();
	rawData.ip = request.ip;
	rawData.ips = request.ips;
	rawData.headers = request.headers;
	rawData.method = request.method;

	var data = {};
	if(request.user){
		data.user = request.user._id;
	}else{
		data.user = "unknown";
	}
	data.rawData = rawData;
	data.eventType = "RequestEvent";
	data.functionType = functionType;
	data.classType = classType;
	data.method = request.method;
	data.startTime = new Date().getTime();
  
  	if(!response.errors){
  		response.errors = []
  	}
	response.on('finish', function(){
		//EWLog("close")
		data.endTime = new Date().getTime();

		data.totalTime = data.endTime - data.startTime
		data.status =  response.statusCode;
		data.problems = response.errors
		EventLog.saveEvent(data, function(err){
		})
	});
};

var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
var ARGUMENT_NAMES = /([^\s,]+)/g;


function getParamNames (func) {
	var fnStr = func.toString().replace(STRIP_COMMENTS, '');
	var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
	if(result === null)
		result = [];
	return result;
}
function construct(constructor, args) {
	function F() {
		return constructor.apply(this, args);
	}
	F.prototype = constructor.prototype;
	return new F();
}
