/***********************************************************************/
/*                                                                     */
/*                      ADOBE CONFIDENTIAL                             */
/*                   _ _ _ _ _ _ _ _ _ _ _ _ _                         */
/*                                                                     */
/*  Copyright 2016 Adobe Systems Incorporated                          */
/*  All Rights Reserved.                                               */
/*                                                                     */
/* NOTICE:  All information contained herein is, and remains           */
/* the property of Adobe Systems Incorporated and its suppliers,       */
/* if any.  The intellectual and technical concepts contained          */
/* herein are proprietary to Adobe Systems Incorporated and its        */
/* suppliers and are protected by all applicable intellectual property */
/* laws, including trade secret and copyright laws.                    */
/* Dissemination of this information or reproduction of this material  */
/* is strictly forbidden unless prior written permission is obtained   */
/* from Adobe Systems Incorporated.                                    */
/*                                                                     */
/***********************************************************************/

function RemoteWorkflowStorage(/*[String]*/ inCacheBasePath, /*[String]*/ inBaseURL)
{
 	var cache = new LocalWorkflowStorage(inCacheBasePath);
 	var baseURL = inBaseURL;
 	var downloadedWorkflowFiles = {};
 	
	//////////////////////////////////////////////////////////////////////////////
	//
	// Return an array consisting of workflows
	//
	this.getWorkflows = function(/*[Function]*/ inCallback)
	{
		throwInvalid(inCallback);

		var callback = inCallback;
		dbglog("RemoteWorkflowStorge.getWorkflows: start");

		cache.getWorkflows(function(inWorkflows)
		{
			var workflows = inWorkflows;
			var downloadCount = 0;
			
			getRemoteWorkflowIDs(function(inFilePaths)
			{
				// download each remote Workflow which isn't cached yet
				//
				if (isValidProperty(inFilePaths))
				{
					var downloadIDs = [];
					
					forEach(inFilePaths, function(filePath)
					{
						if (!isValidProperty(downloadedWorkflowFiles[filePath]))
						{
							downloadIDs.push(filePath);
						}
					});
					
					downloadCount = downloadIDs.length;
					
					forEach(downloadIDs, function(filePath)
					{
						getRemoteWorkflow(filePath, function(){downloadCount--;});
					});
				}
				
				// wait until all download requests have finished
				//
				function wait()
				{
					setTimeout(function()
					{
						if (downloadCount > 0)
						{
							wait();
						}
						else
						{
							cache.getWorkflows(callback);
						}
					}, 50);
				}
				
				wait();
			});
		});
	}
 
	//////////////////////////////////////////////////////////////////////////////
	//
	// Return Workflow object for the given workflow id inID
	//
	this.getWorkflow = function(/*[string]*/ inID, /*[Function]*/ inCallback)
	{
		throwInvalid(inCallback);

		var wfID = inID;
		var callback = inCallback;

		dbglog("RemoteWorkflowStorage.getWorkflow: " + inID);
		
		cache.getWorkflow(inID, function(inCachedWorkflow)
		{
			if (!isValidProperty(inCachedWorkflow))
			{
				getRemoteWorkflow(wfID, callback);
			}
			else if (isValidProperty(callback))
			{
				dbglog("RemoteWorkflowStorage.getWorkflow: cached " + inID);
				callback(inCachedWorkflow);
			}
		});
	}

	// private ///////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////////
	//
	// Download and cache workflow
	//
	function getRemoteWorkflow(/*[string]*/ inFilePath, /*[Function]*/ inCallback)
	{
		var callback = inCallback;
		var filePath = (inFilePath.indexOf('/') == 0) ? inFilePath.substring(1) : inFilePath;
		
		if (navigator.onLine)
		{
			var url = inFilePath;
			if (url.indexOf('http') != 0)
			{
				url = baseURL + filePath;
			}

			getRemoteContent(url, function(inContent)
			{
				if (isValidProperty(inContent))
				{
					downloadedWorkflowFiles[filePath] = true;
					
					// cache it
					var wf = Workflow.create(inContent);

                    if (isValidProperty(wf))
                    {
                        cache.addWorkflow(wf);
                        dbglog("RemoteWorkflowStorage.geRemotetWorkflow: " + wf.id);
                    }

                    // return Workflow
                    if (isValidProperty(callback))
                    {
                        callback(wf);
                    }
				}
				else if (isValidProperty(callback))
				{
					dbglog("RemoteWorkflowStorage.geRemotetWorkflow: null");
					callback(null);
				}
			});
		}
		else if (isValidProperty(callback))
		{
			dbglog("RemoteWorkflowStorage.geRemotetWorkflow: offline " + inFilePath);
			callback(null);
		}
	}
	
	//////////////////////////////////////////////////////////////////////////////
	//
	// Get all workflows IDs from remote
	//
	function getRemoteWorkflowIDs(/*[Function]*/ inCallback)
	{
		var callback = inCallback;
		
		if (navigator.onLine)
		{
			getRemoteContent(baseURL + 'workflows.lst', function(inContent)
			{
				if (isValidProperty(inContent))
				{
					var ret = inContent.split('\n');
					
					if (isValidProperty(callback))
					{
						dbglog("RemoteWorkflowStorge.getRemoteWorkflowIDs: " + (isValidProperty(ret) ? ret.toString() : ''));
						callback(ret);
					}
				}
				else if (isValidProperty(callback))
				{
					dbglog("RemoteWorkflowStorge.getRemoteWorkflowIDs: null");
					callback(null);
				}
			});
		}
		else if (isValidProperty(callback))
		{
			dbglog("RemoteWorkflowStorge.getRemoteWorkflowIDs: offline");
			callback(null);
		}
	}
	
	//////////////////////////////////////////////////////////////////////////////
	//
	// Download and cache remote resource
	//
	function getRemoteContent(/*[String]*/ inURL, /*[Function]*/ inCallback)
	{
		var callback = inCallback;

		dbglog("RemoteWorkflowStorge.getRemoteContent: " + inURL);

		function onSuccess(/*[XMKHttpRequest]*/ inRequest)
		{
			dbglog("RemoteWorkflowStorge.getRemoteContent: status " + inRequest.status);

			if (isValidProperty(callback))
			{
				if (inRequest.status == 200)
				{
					// success
					var data = inRequest.responseText;
					callback(data);
				}
				else
				{
					callback(null);
				}
			}
		}

		function onAborted(/*[XMLHttpRequest]*/ inRequest, /*[String]*/ inReason)
		{
			dbglog("RemoteWorkflowStorge.getRemoteContent: " + inReason);
			if (isValidProperty(callback))
			{
				callback(null);
			}
		}

		requestRemoteContent(inURL, onSuccess, onAborted);
	}

	//////////////////////////////////////////////////////////////////////////////
	//
	// Initialize
	//
	(function()
	{
		var res = cep.fs.stat(inCacheBasePath);
		
		if (isValidProperty(res) && res.err != cep.fs.NO_ERROR)
		{
			cep.fs.makedir(inCacheBasePath);
		}
	})();
}