/***********************************************************************/
/*                                                                     */
/*                      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 RemoteContentStorage(/*[String]*/ inCacheBasePath, /*[String]*/ inBaseURL)
{
	var cacheBasePath = inCacheBasePath;
 	var cache = (isValidProperty(inCacheBasePath) ? new LocalContentStorage(inCacheBasePath) : new MemoryContentStorage());
 	var baseURL = inBaseURL;
 	var fileCaching = isValidProperty(inCacheBasePath);
 
	//////////////////////////////////////////////////////////////////////////////
	//
	// Return absolute url of content file
	//
	this.getURL = function(/*[string]*/ inWorkflowID, /*[string]*/ inContentID, /*[Function]*/ inCallback)
	{
		throwInvalid(inCallback);

		var workflowID = inWorkflowID;
		var contentID = inContentID;

		var callback = function(/*[String]*/ inURL)
		{
			dbgLogContent("RemoteContentStorage.getURL", workflowID, contentID, null, inURL);
			inCallback(inURL);
		}

		cache.getURL(workflowID, contentID, function(url)
		{
			if (isValidProperty(url))
			{
				callback(url);
			}
			else
			{
				url = getContentURL(workflowID, contentID, true);

				requestRemoteContentExists(url, function (exists)
				{
					if (exists)
					{
						if (!fileCaching)
						{
							cache.setURL(workflowID, contentID, url);
						}

						callback(url);
					}
					else
					{
						url = getContentURL(workflowID, contentID, false);

						requestRemoteContentExists(url, function (exists)
						{
							if (!fileCaching && exists)
							{
								cache.setURL(workflowID, contentID, url);
							}

							callback(exists ? url : null);
						});
					}
				});
			}
		});
	}
 
	//////////////////////////////////////////////////////////////////////////////
	//
	// Return content as it is (e.g. raw text is returned as raw text, html is returned as html, etc.)
	//
	this.getRaw = function(/*[string]*/ inWorkflowID, /*[string]*/ inContentID, /*[Function]*/ inCallback)
	{
		throwInvalid(inCallback);

		var workflowID = inWorkflowID;
		var contentID = inContentID;
		var doFileCaching = fileCaching;

		var callback = function(/*[String]*/ inContent)
		{
			dbgLogContent("RemoteContentStorage.getRaw", workflowID, contentID, null, inContent);
			inCallback(inContent);
		}

		var doDownload = function(/*[String]*/ inURL, /*[String]*/ inCachedPath)
		{
			if (isValidProperty(inURL))
			{
				if (doFileCaching)
				{
					downloadFile(inURL, inCachedPath, function(content)
					{
						cache.getRaw(workflowID, contentID, callback);
					});
				}
				else
				{
					download(inURL, function(inRequest)
					{
						var ret = null;

						if (inRequest.status == 200)
						{
							// success
							ret = inRequest.responseText;
						}

						if (isValidProperty(ret))
						{
							cache.setRaw(workflowID, contentID, ret);
						}

						callback(ret);
					});
				}
			}
		}

		cache.getRaw(workflowID, contentID, function(content)
		{
			if (isValidProperty(content))
			{
				callback(content);
			}
			else
			{
				var cachedPath = null;
				var url = getContentURL(workflowID, contentID, true);

				requestRemoteContentExists(url, function (exists)
				{
					if (exists)
					{
						cachedPath = getContentPath(workflowID, contentID, true);
						doDownload(url, cachedPath);
					}
					else
					{
						url = getContentURL(workflowID, contentID, false);

						requestRemoteContentExists(url, function (exists)
						{
							if (exists)
							{
								cachedPath = getContentPath(workflowID, contentID, true);
								doDownload(url, cachedPath);
							}
							else
							{
								callback(null);
							}
						});
					}
				});
			}
		});
	}
 
	//////////////////////////////////////////////////////////////////////////////
	//
	// Return content from string table
	//
	this.getString = function(/*[string]*/ inWorkflowID, /*[string]*/ inContentID, /*[Function]*/ inCallback)
	{
		throwInvalid(inCallback);

		var workflowID = inWorkflowID;
		var contentID = inContentID;
		var doFileCaching = fileCaching;

		var callback = function(/*[String]*/ inContent)
		{
			dbgLogContent("RemoteContentStorage.getString", workflowID, contentID, null, inContent);
			inCallback(inContent);
		}

		var doDownload = function(/*[String]*/ inURL, /*[String]*/ inCachedPath)
		{
			if (isValidProperty(inURL))
			{
				if (doFileCaching)
				{
					downloadFile(inURL, inCachedPath, function(content)
					{
						cache.getString(workflowID, contentID, callback);
					});
				}
				else
				{
					download(inURL, function(inRequest)
					{
						var ret = '';

						if (inRequest.status == 200)
						{
							// success
							var stringtable = new StringTable();
							stringtable.setData(inRequest.responseText);
							cache.setStringtable(workflowID, stringtable);
							cache.getString(workflowID, contentID, callback);
						}
						else
						{
							callback(ret);
						}
					});
				}
			}
		}

		cache.getString(inWorkflowID, inContentID, function(content)
		{
			if (isValidProperty(content) && content.length > 0)
			{
				callback(content);
			}
			else
			{
				var cachedPath = null;
				var url = getContentURL(workflowID, StringTable.FILENAME, true);

				requestRemoteContentExists(url, function (exists)
				{
					if (exists)
					{
						cachedPath = getContentPath(workflowID, StringTable.FILENAME, true);
						doDownload(url, cachedPath);
					}
					else
					{
						url = getContentURL(workflowID, StringTable.FILENAME, false);

						requestRemoteContentExists(url, function (exists)
						{
							if (exists)
							{
								cachedPath = getContentPath(workflowID, StringTable.FILENAME, true);
								doDownload(url, cachedPath);
							}
							else
							{
								callback(null);
							}
						});
					}
				});
			}
		});
	}
	
	// private ///////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////////////
	//
	// Create remote url for content
	//
	function getContentURL(/*[string]*/ inWorkflowID, /*[string]*/ inContentID, /*[Boolean]*/ inLocalized)
	{
		var url = '';
		
		if (inContentID.indexOf('http') == 0)
		{
			url = inContentID;
			
			if (inLocalized)
			{
				var pos = url.lastIndexOf('/');
				
				if (pos >= 0)
				{
					var tmp = url.substring(0, pos);
					tmp += '/';
					tmp += getLocale();
					tmp += url.substring(pos);
					url = tmp;
				}
			}
		}
		else
		{
			url = baseURL + inWorkflowID + '/';
			
			if (inLocalized)
			{
				url += getLocale() + '/';
			}

			url += inContentID;
		}

		dbgLogContent("RemoteContentStorage.getContentURL", inWorkflowID, inContentID, inLocalized, url);
		
		return url;
	}
	
	//////////////////////////////////////////////////////////////////////////////
	//
	// Download file synchronously
	//
	function download(/*[String]*/ inURL, /*[Function]*/ inDownloadHdl)
	{
		dbglog("RemoteContentStorage.download: ", inURL);

		var url = inURL;
		var callback = inDownloadHdl;

		function onSuccess(/*[XMKHttpRequest]*/ inRequest)
		{
			if (isValidProperty(callback))
			{
				if (inRequest.status == 200)
				{
					// success
					dbglog("RemoteContentStorage.download: ", url + " success");
					callback(inRequest);
				}
				else
				{
					dbglog("RemoteContentStorage.download: ", url + " failed");
					callback(null);
				}
			}
		}

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

		requestRemoteContent(url, onSuccess, onAborted);
	}
	
	//////////////////////////////////////////////////////////////////////////////
	//
	// Download file synchronously and save in cache
	//
	function downloadFile(/*[String]*/ inURL, /*[String]*/ inCachedFilePath, /*[Function]*/ inResultHdl)
	{
		var ret = false;
		var cachedFilePath = inCachedFilePath;
		var resultHdl = inResultHdl;
		
		download(inURL, function(inRequest)
		{
			var content = null;
			if (inRequest.status == 200)
			{
				// success
				content = inRequest.responseText;
				cep.fs.writeFile(inCachedFilePath, content);
			}

			resultHdl(content);
		});
	}

	//////////////////////////////////////////////////////////////////////////////
	//
	// Create path to content file 
	// (if inContentID is a filename)
	//
	function getContentPath(/*[string]*/ inWorkflowID, /*[string]*/ inContentID, /*[Boolean]*/ inLocalized)
	{
		var localized = isValidProperty(inLocalized) && inLocalized;
		var wfPath = isValidProperty(inWorkflowID) ? (inWorkflowID + '/') : '';
		var ret = cacheBasePath + wfPath + (localized ? (getLocale() + '/') : '') + inContentID;

		dbgLogContent("RemoteContentStorage.getContentPath", inWorkflowID, inContentID, inLocalized, ret);

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