<commit_before>var http = require('follow-redirects').http;
var util = require('util');
var requestPckg = require('request');

var kaltura = module.exports = require('../KalturaManager');

require('../utils/KalturaUrlTokenMapper');
require('../adServingProtocols/vast/KalturaVastParser');
var kalturaMediaInfo = require('../media/KalturaMediaInfo');
var kalturaAspectRatio = require('../media/KalturaAspectRatio');
var parseString = require('xml2js').parseString;

/**
 * @service adIntegration
 */
var KalturaAdIntegrationManager = function(){
	this.initClient(KalturaConfig.config.client);
};
util.inherits(KalturaAdIntegrationManager, kaltura.KalturaManager);

/**
 * Fetch cue-points from cache and trigger stitching with the player info
 * 
 * @action adIntegration.stitch
 * 
 * @param entryId 
 * @param uiConfId 
 * @param sessionId
 */
KalturaAdIntegrationManager.prototype.stitch = function(request, response, params){
	params = this.parsePlayServerParams(response, params, ['entryId', 'uiConfId', 'sessionId']);
	if(!params){
		this.errorMissingParameter(response);
		return;
	}
	
	response.dir(params);

	var This = this;
	var encodingIds = [];
	var uiConfConfig = null;
	var cuePointsKey = KalturaCache.getCuePoints(params.entryId);
	var elapsedTimeKey = KalturaCache.getElapsedTime(params.entryId);
	var entryRequiredKey = KalturaCache.getEntryRequired(params.entryId);
	var uiConfConfigKey = KalturaCache.getUiConfConfig(params.uiConfId);
	
	KalturaCache.getMulti([cuePointsKey, elapsedTimeKey, entryRequiredKey, uiConfConfigKey], function(data){
		response.debug('handled');
		response.writeHead(200);
		response.end('OK');
		
		if(data[entryRequiredKey])
			encodingIds = data[entryRequiredKey].split('\n').unique();
		
		if(!data[uiConfConfigKey]){
			This.getAndStoreUiConfConfig(params.uiConfId, params.entryId, params.partnerId, function(uiConfConfigRes) {
				uiConfConfig = uiConfConfigRes;
				This.stitchCuePoints(request, response, params, data[cuePointsKey], data[elapsedTimeKey], encodingIds, uiConfConfig);
			});			
		}
		else{
			uiConfConfig = data[uiConfConfigKey];
			This.stitchCuePoints(request, response, params, data[cuePointsKey], data[elapsedTimeKey], encodingIds, uiConfConfig);
		}		
	}, function(err){
		response.error(msg);
		This.errorResponse(response, 500, msg);
	});		

};


/**
 * Fetch cue-points from cache and trigger stitching with the player info
 * 
 * @param entryId 
 * @param uiConfId 
 * @param sessionId
 */
KalturaAdIntegrationManager.prototype.stitchCuePoints = function(request, response, params, cuePoints, elapsedTime, encodingIds, uiConfConfig){
	var This = this;
	var encodingIdsKeys = [];
	var mediaInfos = null;
	var entry = null;
	var metadata = null;	
	var metadataProfileId = null;
	
	for(var i = 0; i < encodingIds.length; i++){ 
		if(encodingIds[i].trim().length)
			encodingIdsKeys.push(KalturaCache.getMediaInfo(encodingIds[i]));
	}
				
	KalturaCache.getMulti(encodingIdsKeys, function(mediaInfoData){
		mediaInfos = mediaInfoData;
			
	 	if(!cuePoints || !elapsedTime || !encodingIds){
	   		return;
	   	}
	   			   		
	   	var tenMinutes = 10 * 60 * 1000;
	    		
	   	var timeWindowStart = elapsedTime.timestamp - tenMinutes;
	   	var timeWindowEnd = elapsedTime.timestamp + tenMinutes;
	   
	   	var offsetWindowStart = elapsedTime.offset - tenMinutes;
	   	var offsetWindowEnd = elapsedTime.offset + tenMinutes;	
		
	   	var playerConfig = null;
	   	if(params.playerConfig){
	   		playerConfig = JSON.parse(params.playerConfig);
	   		if(playerConfig){
	   			metadataProfileId = playerConfig['metadataProfileId'];
	   		}	   		
	   	}
	   	
	   	for(var cuePointId in cuePoints){
	   		cuePoint = cuePoints[cuePointId];
	   		var cuePointUrlKey = KalturaCache.getCuePointUrl(cuePoint.id);
			var cuePointHandledKey = KalturaCache.getCuePointHandled(cuePointId, params.sessionId);
	   		if( (cuePoint.triggeredAt && timeWindowStart < cuePoint.triggeredAt*1000 && cuePoint.triggeredAt*1000 < timeWindowEnd) ||
	   			(cuePoint.startTime && offsetWindowStart < cuePoint.startTime && cuePoint.startTime < offsetWindowEnd)){
				KalturaCache.add(cuePointHandledKey, true, KalturaConfig.config.cache.cuePoint, function(){					
					KalturaCache.get(cuePointUrlKey, function(cachedUrl){
						if(cachedUrl){
							response.debug('Cue point url found in cache: [' + cachedUrl + ']');
							This.stitchAd(request, response, params.partnerId, cachedUrl, cuePoint, entry, metadata, playerConfig, mediaInfos, params.sessionId, uiConfConfig);
						}
						else{
							response.debug('Cue point url not found in cache');
							if(!entry){
								This.getEntryAndMetadata(params.partnerId, params.entryId, metadataProfileId, function(entryObj, metadataObj){
									entry = entryObj;
									metadata = metadataObj;
									This.stitchAd(request, response, params.partnerId, null, cuePoint, entry, metadata, playerConfig, mediaInfos, params.sessionId, uiConfConfig);
								});
							}	   						
						}
						}, function (err) {
							response.debug('Cue point url not found in cache: ' + err);
							if(!entry){
								This.getEntryAndMetadata(params.partnerId, params.entryId, metadataProfileId, function(entryObj, metadataObj){
									entry = entryObj;
									metadata = metadataObj;
									This.stitchAd(request, response, null, params.partnerId, cuePoint, entry, metadata, playerConfig, mediaInfos, params.sessionId, uiConfConfig);
								});
							}	   						
						});
				}, function(err){
					response.debug('cue point [' + cuePointId + '] for session [' + params.sessionId + '] already handled');
				});
	   		}
	   	}
	});		
};

/**
 * Stitch specific cue point
 * @param request
 * @param response
 * @param cachedUrl
 * @param cuePoint
 * @param entry
 * @param metadata<commit_msg>#PLAT-2331 fix cue points async loop<commit_after>var http = require('follow-redirects').http;
var util = require('util');
var requestPckg = require('request');

var kaltura = module.exports = require('../KalturaManager');

require('../utils/KalturaUrlTokenMapper');
require('../adServingProtocols/vast/KalturaVastParser');
var kalturaMediaInfo = require('../media/KalturaMediaInfo');
var kalturaAspectRatio = require('../media/KalturaAspectRatio');
var parseString = require('xml2js').parseString;

/**
 * @service adIntegration
 */
var KalturaAdIntegrationManager = function(){
	this.initClient(KalturaConfig.config.client);
};
util.inherits(KalturaAdIntegrationManager, kaltura.KalturaManager);

/**
 * Fetch cue-points from cache and trigger stitching with the player info
 * 
 * @action adIntegration.stitch
 * 
 * @param entryId 
 * @param uiConfId 
 * @param sessionId
 */
KalturaAdIntegrationManager.prototype.stitch = function(request, response, params){
	params = this.parsePlayServerParams(response, params, ['entryId', 'uiConfId', 'sessionId']);
	if(!params){
		this.errorMissingParameter(response);
		return;
	}
	
	response.dir(params);

	var This = this;
	var encodingIds = [];
	var uiConfConfig = null;
	var cuePointsKey = KalturaCache.getCuePoints(params.entryId);
	var elapsedTimeKey = KalturaCache.getElapsedTime(params.entryId);
	var entryRequiredKey = KalturaCache.getEntryRequired(params.entryId);
	var uiConfConfigKey = KalturaCache.getUiConfConfig(params.uiConfId);
	
	KalturaCache.getMulti([cuePointsKey, elapsedTimeKey, entryRequiredKey, uiConfConfigKey], function(data){
		response.debug('handled');
		response.writeHead(200);
		response.end('OK');
		
		if(data[entryRequiredKey])
			encodingIds = data[entryRequiredKey].split('\n').unique();
		
		if(!data[uiConfConfigKey]){
			This.getAndStoreUiConfConfig(params.uiConfId, params.entryId, params.partnerId, function(uiConfConfigRes) {
				uiConfConfig = uiConfConfigRes;
				This.stitchCuePoints(request, response, params, data[cuePointsKey], data[elapsedTimeKey], encodingIds, uiConfConfig);
			});			
		}
		else{
			uiConfConfig = data[uiConfConfigKey];
			This.stitchCuePoints(request, response, params, data[cuePointsKey], data[elapsedTimeKey], encodingIds, uiConfConfig);
		}		
	}, function(err){
		response.error(msg);
		This.errorResponse(response, 500, msg);
	});		

};


/**
 * Fetch cue-points from cache and trigger stitching with the player info
 * 
 * @param entryId 
 * @param uiConfId 
 * @param sessionId
 */
KalturaAdIntegrationManager.prototype.stitchCuePoints = function(request, response, params, cuePoints, elapsedTime, encodingIds, uiConfConfig){
	var This = this;
	var encodingIdsKeys = [];
	var mediaInfos = null;
	var entry = null;
	var metadata = null;	
	var metadataProfileId = null;
	
	for(var i = 0; i < encodingIds.length; i++){ 
		if(encodingIds[i].trim().length)
			encodingIdsKeys.push(KalturaCache.getMediaInfo(encodingIds[i]));
	}
				
	KalturaCache.getMulti(encodingIdsKeys, function(mediaInfoData){
		mediaInfos = mediaInfoData;
			
	 	if(!cuePoints || !elapsedTime || !encodingIds){
	   		return;
	   	}
	   			   		
	   	var tenMinutes = 10 * 60 * 1000;
	    		
	   	var timeWindowStart = elapsedTime.timestamp - tenMinutes;
	   	var timeWindowEnd = elapsedTime.timestamp + tenMinutes;
	   
	   	var offsetWindowStart = elapsedTime.offset - tenMinutes;
	   	var offsetWindowEnd = elapsedTime.offset + tenMinutes;	
		
	   	var playerConfig = null;
	   	if(params.playerConfig){
	   		playerConfig = JSON.parse(params.playerConfig);
	   		if(playerConfig){
	   			metadataProfileId = playerConfig['metadataProfileId'];
	   		}	   		
	   	}
	   	
	   	var handleCuePoint = function(cuePoint){
	   		var cuePointUrlKey = KalturaCache.getCuePointUrl(cuePoint.id);
			var cuePointHandledKey = KalturaCache.getCuePointHandled(cuePoint.id, params.sessionId);
	   		if( (cuePoint.triggeredAt && timeWindowStart < cuePoint.triggeredAt*1000 && cuePoint.triggeredAt*1000 < timeWindowEnd) ||
	   			(cuePoint.startTime && offsetWindowStart < cuePoint.startTime && cuePoint.startTime < offsetWindowEnd)){
				KalturaCache.add(cuePointHandledKey, true, KalturaConfig.config.cache.cuePoint, function(){					
					KalturaCache.get(cuePointUrlKey, function(cachedUrl){
						if(cachedUrl){
							response.debug('Cue point url found in cache: [' + cachedUrl + '] for cue point [' + cuePoint.id + ']');
							This.stitchAd(request, response, params.partnerId, cachedUrl, cuePoint, entry, metadata, playerConfig, mediaInfos, params.sessionId, uiConfConfig);
						}
						else{
							response.debug('Cue point url not found in cache for cue point [' + cuePoint.id + ']');
							if(!entry){
								This.getEntryAndMetadata(params.partnerId, params.entryId, metadataProfileId, function(entryObj, metadataObj){
									entry = entryObj;
									metadata = metadataObj;
									This.stitchAd(request, response, params.partnerId, null, cuePoint, entry, metadata, playerConfig, mediaInfos, params.sessionId, uiConfConfig);
								});
							}	   						
						}
						}, function (err) {
							response.debug('Cue point url not found in cache for cue point [' + cuePoint.id + ']: ' + err);
							if(!entry){
								This.getEntryAndMetadata(params.partnerId, params.entryId, metadataProfileId, function(entryObj, metadataObj){
									entry = entryObj;
									metadata = metadataObj;
									This.stitchAd(request, response, null, params.partnerId, cuePoint, entry, metadata, playerConfig, mediaInfos, params.sessionId, uiConfConfig);
								});
							}	   						
						});
				}, function(err){
					response.debug('cue point [' + cuePoint.id + '] for session [' + params.sessionId + '] already handled');
				});
	   		}	   		
	   	};
	   	
	   	for(var cuePointId in cuePoints){
	   		cuePoint = cuePoints[cuePointId];
	   		handleCuePoint(cuePoint);
	   	}
	});		
};

/**
 * Stitch specific cue point
 * @param request
 * @param response
 * @param cachedUrl
 * @param cuePoint
 * @param entry
 * @param metadata
{'fraction_non_alphanumeric': 0.12090424180848362, 'fraction_numerical': 0.004402675472017611, 'mean_word_length': 4.030664395229983, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3006719', 'n_tokens_mistral': 4370, 'n_tokens_neox': 3655, 'n_words': 714}