bam.imports(bam.soap, bam.object, bam.xml);
// MediaService
var MediaService = (function(){
	bam.loadSync('/shared/scripts/bam/packed/bam.cookies.js');

	var _proxy  = "/pubajaxws/services/MediaService2_0";
	var _devURL = "http://dev-a.services.bamnetworks.com:8888/ws/services/MediaService2_0";

	// 
	var _consoleLevel = 0,
		_waitingRoom = false;

	/**
	 * Alias for debugging loger
	 */
	function _console(method,arg){
		if (_consoleLevel>0){
			if (typeof window.console!=='undefined'){ console[method](arg); }
			else if (typeof arg==='string')	{ throw new Error(arg); } 
		}
	}

	/**
	 * Parses status node of Media Service 2.0 SOAP response 
	 */
	function _getStatus(responseBodyElement){
		var status = {
			code : responseBodyElement.status_code[0].Text
		};

		switch (status.code){
			case '-1000': 
				status.msg = 'Requested media not found';
				break;
			case '-2000':
				status.msg = 'Invalid App Account Information';
				break;
			case '-3000':
				status.msg = 'Invalid user credentials';
				break;
			case '-3500':
				status.msg = 'Sign-on restriction status';
				break;
			case '-4000':
				status.msg = 'System Error';
				break;
			default:
				status.msg = 'Unknown Error';
				break;
		}
	
		return status;
	}

	/**
	 * Creates request body for Media Service SOAP request
	 */
	function _createRequestBody(requestBodyElementName){
		// Create the request soap object
		var bodyObj    = new bam.soap.SOAPObject(requestBodyElementName);
			bodyObj.ns = "http://services.bamnetworks.com/media/types/2.0";

		return bodyObj;
	}

	/**
	 * Creates identification node
	 */
	function _createFprtIpidNode(){
		var ipid      = bam.cookies.get('ipid');
		var fprt      = unescape(bam.cookies.get('fprt'));
		var fprt_ipid = null;

		if (!!!ipid) { _console('log','MediaService2_0: missing identity point id'); }
		if (!!!fprt) { _console('log','MediaService2_0: missing fingerprint'); }

		if (!!ipid && !!fprt){
			fprt_ipid = new bam.soap.SOAPObject("fingerprint-identity-point");
			fprt_ipid.appendChild(new bam.soap.SOAPObject("identity-point-id").val(ipid.toString()));
			fprt_ipid.appendChild(new bam.soap.SOAPObject("fingerprint").val(fprt.toString()));
		}

		return fprt_ipid;
	}

	/**
	 * Builds SOAP structure for Media Service 2.0 request
	 */
	function _appendMediaRequestNodes(soapBody, mediaParams){ //event_id, ipid, fprt, content_id, playback_scenario
		var mediaParamValue, isVerifiedUserRequest, sessionKey;
		if (typeof mediaParams==='object'){

			isVerifiedUserRequest = mediaParams.isVerifiedUserRequest;
			delete mediaParams.isVerifiedUserRequest;

			sessionKey = mediaParams.session_key;
			delete mediaParams.session_key;

			for (var mediaParam in mediaParams){
				if (!!mediaParams[mediaParam]){
					mediaParamValue = mediaParams[mediaParam].toString();
					soapBody.appendChild(new bam.soap.SOAPObject(mediaParam.replace('_','-')).val(mediaParamValue));
				}
			}

			if (!!isVerifiedUserRequest)	{			
				var fprtIpid = _createFprtIpidNode();
				if (!!fprtIpid) { soapBody.appendChild(fprtIpid); }
			}

			if (!!sessionKey){
				soapBody.appendChild(new bam.soap.SOAPObject('session-key').val(sessionKey.toString()));
			}
		}
		else{
			throw new Error('MediaService2_0: invalid mediaParams object');
		}
	}

	/**
	 * Checks if response contains service error
	 */
	function _isErrorThrown(responseBodyElement){
		return responseBodyElement.status_code && responseBodyElement.status_code[0].Text != 1;
	}

	/**
	 * Converts media service 2.0 soap response to JSON
	 */
	function _soapToMediaResponse(soapObject){
		var mediaResponse = null;

		if (typeof soapObject==='object'){

			if (!!soapObject._children || !!soapObject._attributes){
				if (!!soapObject._children){
					var c=0, childName, child;
					mediaResponse = {};

					do{
						childName                = soapObject._children[c];
						child                    = soapObject[childName];
						mediaResponse[childName] = child.length>1 ? _soapToMediaResponse(child) : _soapToMediaResponse(child[0]);
						c++;
					}
					while (c<soapObject._children.length);
				}
			}
			else if (soapObject.length>1){
				var i=0;
				mediaResponse = [];
				do{
					if (!!soapObject[i]._children || !!soapObject[i]._attributes){ 
						if (!!soapObject[i]._attributes && !!soapObject[i].name){
							mediaResponse.push({name:soapObject[i].name, value:soapObject[i].Text});
						}
						else {
							mediaResponse.push(_soapToMediaResponse(soapObject[i])); 
						}
					}
					else if (!!soapObject[i].Text){ 
						mediaResponse.push(soapObject[i].Text); 
					}
					i++;
				} while(i<soapObject.length);
			}
			else if (!!soapObject.Text){
				mediaResponse = soapObject.Text;
			}	
		}

		return mediaResponse;
	}

	function _createMediaRequestObject(mediaParams){
		var mediaParamValue, isVerifiedUserRequest, paramObj = null, arrParamName;
		if (typeof mediaParams==='object'){
			paramObj = {};

			isVerifiedUserRequest = mediaParams.isVerifiedUserRequest;
			delete mediaParams.isVerifiedUserRequest;
			delete mediaParams.requestType;

			if (!!isVerifiedUserRequest)	{			
				var ipid      = bam.cookies.get('ipid');
				var fprt      = unescape(bam.cookies.get('fprt'));
				var fprt_ipid = null;

				if (!!!ipid) { _console('log','MediaService2_0: missing identity point id'); }
				if (!!!fprt) { _console('log','MediaService2_0: missing fingerprint'); }

				if (!!ipid && !!fprt){
					paramObj.identityPointId = ipid.toString();
					paramObj.fingerprint     = fprt.toString();
				}
			}

			for (var mediaParam in mediaParams){
				if (!!mediaParams[mediaParam]){
					mediaParamValue = mediaParams[mediaParam].toString();
					if (mediaParam.indexOf('_')!==-1){
						arrParamName = mediaParam.split('_');
						for (var w=1; w<arrParamName.length; w++){
							arrParamName[w] = arrParamName[w].charAt(0).toUpperCase() + arrParamName[w].substring(1);
						}
						mediaParam = arrParamName.join('');
					}
					paramObj[mediaParam] = mediaParamValue;
				}
			}
		}
		else{
			throw new Error('MediaService2_0: invalid mediaParams object');
		}
		return paramObj;
	}
	
	function _soapRequest(p){
		var params = {
				isVerifiedUserRequest : (typeof p.isVerifiedUserRequest!=='undefined' && p.isVerifiedUserRequest!=null) ? p.isVerifiedUserRequest : true,
				event_id              : p.event_id || null,
				content_id            : p.content_id || null,
				playback_scenario     : p.playback_scenario || null,
				subject               : p.subject || 'LIVE_EVENT_COVERAGE',
				session_key           : p.session_key || null
			},
			success = (!!p.success && typeof p.success === 'function') ? p.success : null,
			error   = (!!p.error && typeof p.error === 'function') ? p.error : null;

			_console('group','MEDIA SERVICE 2.0: Request Media');

			bam.soap.SOAPClient.Proxy      = _proxy;
			bam.soap.SOAPClient.SOAPServer = _devURL;

			var soapBody       = _createRequestBody("user-verified-media-request");
			var requestElement = _appendMediaRequestNodes(soapBody, params);

			var soapRequest = new bam.soap.SOAPRequest("find", soapBody);
			bam.soap.SOAPClient.SendRequest(soapRequest, function(data)
			{
				if (data && data.Body && data.Body[0].user_verified_media_response)
				{
					var responseBodyElement = data.Body[0].user_verified_media_response[0];

					if (!!!_isErrorThrown(responseBodyElement)){
						if (typeof success === 'function'){
							var mediaResponse = _soapToMediaResponse(responseBodyElement);
							_console('dir',mediaResponse);
							success(mediaResponse);
						}
						else{
							_console('error','MediaService2_0.requestMedia: success handler is not a function');
						}
					}
					else{
						if (typeof error === 'function'){
							var oError       = _getStatus(responseBodyElement);
							oError.operation = "MediaService.requestMedia";
							error(oError);
						}
						else{
							_console('error','MediaService2_0.requestMedia: errorCallback is not a function');
						}
					}
				}
				else{
					if (typeof error === 'function'){
						error({operation:'MediaService2_0.requestMedia', code:-100000, message:'bad data'});
					}
					else{
						_console('error','MediaService2_0.requestMedia: errorCallback is not a function');
					}
				}
			});

			_console('groupEnd','END MEDIA SERVICE 2.0: Request Media'); 
	}


	function _restRequest(p){
		var params = {
				isVerifiedUserRequest : (typeof p.isVerifiedUserRequest!=='undefined' && p.isVerifiedUserRequest!=null) ? p.isVerifiedUserRequest : true,
				event_id              : p.event_id || null,
				content_id            : p.content_id || null,
				playback_scenario     : p.playback_scenario || null,
				subject               : p.subject || 'LIVE_EVENT_COVERAGE',
				session_key           : p.session_key || null
			},
			success = (!!p.success && typeof p.success === 'function') ? p.success : null,
			error   = (!!p.error && typeof p.error === 'function') ? p.error : null,
			requestObject = _createMediaRequestObject(params);

			$.ajax({
				url     : '/pubajaxws/bamrest/MediaService2_0/op-findUserVerifiedEvent/v-2.0',
				data    : requestObject,
				success : function(response){
					bam.loadSync('/shared/scripts/bam/packed/bam.cookies.js');

					var data;
					// handle waiting room response
					var waitingRoomToken = bam.cookies.get('NSC_BPIP');
					if (!!waitingRoomToken && !_waitingRoom) { 
						_waitingRoom=true;
						setTimeout(function(){
							_mediaService.requestMedia(p); 
							bam.cookies.remove({name:'NSC_BPIP',path:'/'});
						},1000);
					}
					// process service response
					else {
						_waitingRoom=false;
						bam.loadSync('/shared/scripts/bam/packed/bam.xml.js');
						data = bam.xml.xmlToJSON(response);
						if (data.RootName==='user_verified_media_response')
						{
							var responseBodyElement = data;

							if (!!!_isErrorThrown(responseBodyElement)){
								if (typeof success === 'function'){
									var mediaResponse = _soapToMediaResponse(responseBodyElement);
									_console('dir',mediaResponse);
									success(mediaResponse);
								}
								else{
									_console('error','MediaService2_0.requestMedia: success handler is not a function');
								}
							}
							else{
								if (typeof error === 'function'){
									var oError       = _getStatus(responseBodyElement);
									oError.operation = "MediaService.requestMedia";
									error(oError);
								}
								else{
									_console('error','MediaService2_0.requestMedia: errorCallback is not a function');
								}
							}
						}
						else{
							if (typeof error === 'function'){
								error({operation:'MediaService2_0.requestMedia', code:-100000, message:'bad data'});
							}
							else{
								_console('error','MediaService2_0.requestMedia: errorCallback is not a function');
							}
						}
						_waitingRoom=false;
					}
				}
			});

	}

	var _mediaService = {
		setLogLevel: function(level){
			_consoleLevel = level;
		},

		/**
		 * Requests media from MediaService2_0
		 */
		requestMedia: function(p){
			if (!!p.requestType && p.requestType==='soap'){
				_soapRequest(p);
			}	
			else {
				_restRequest(p);
			}
		}
	};

	return _mediaService;
})();

