/***********************************************************************/
/*                                                                     */
/*                      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 MultiContentStorage(/*[Array]*/ inContentBasePaths, /*[String]*/ inBaseURL, /*[String]*/ inCacheBasePath)
{
	var localStorage = [];
	var remoteStorage = ((isValidProperty(inBaseURL) && inBaseURL.length) ? new RemoteContentStorage(inCacheBasePath, inBaseURL) : null);
 
 	var blacklist = {};
 	
	//////////////////////////////////////////////////////////////////////////////
	//
	// 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("MultiContentStorage.getURL", workflowID, contentID, null, inURL);
			inCallback(inURL);
		}
	
		if (!isBlackList(workflowID, contentID))
		{
			var found = false;
			for (var index=0; index<localStorage.length && !found; index++)
			{
				localStorage[index].getURL(workflowID, contentID, function(url)
				{
					found = isValidProperty(url);

					if (found)
					{
						callback(url);
					}
				});
			}

			if (isValidProperty(remoteStorage))
			{
				if (!found)
				{
					remoteStorage.getURL(workflowID, contentID, function(url)
					{
						callback(url);

						if (!isValidProperty(url))
						{
							addBlackList(workflowID, contentID);
						}
					});
				}
			}
			else
			{
				if (!found)
				{
					addBlackList(workflowID, contentID);
					callback(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 callback = function(/*[String]*/ inContent)
		{
			dbgLogContent("MultiContentStorage.getRaw", workflowID, contentID, null, inContent);
			inCallback(inContent);
		}

		if (!isBlackList(inWorkflowID, inContentID))
		{
			var found = false;
			for (var index=0; index<localStorage.length && !found; index++)
			{
				localStorage[index].getRaw(inWorkflowID, inContentID, function(content)
				{
					found = isValidProperty(content);

					if (found)
					{
						callback(content);
					}
				});
			}

			if (isValidProperty(remoteStorage))
			{
				if (!found)
				{
					remoteStorage.getRaw(workflowID, contentID, function(content)
					{
						callback(content);

						if (!isValidProperty(content))
						{
							addBlackList(workflowID, contentID);
						}
					});
				}
			}
			else
			{
				if (!found)
				{
					addBlackList(workflowID, contentID);
					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 callback = function(/*[String]*/ inString)
		{
			dbgLogContent("MultiContentStorage.getString", workflowID, contentID, null, inString);
			inCallback(inString);
		}

		if (!isBlackList(inWorkflowID, inContentID))
		{
			var found = false;
			for (var index=0; index<localStorage.length && !found; index++)
			{
				localStorage[index].getString(inWorkflowID, inContentID, function(content)
				{
					found = isValidProperty(content) && content.length;

					if (found)
					{
						callback(content);
					}
				});
			}

			if (isValidProperty(remoteStorage))
			{
				if (!found)
				{
					remoteStorage.getString(workflowID, contentID, function(content)
					{
						callback(content);

						if (!isValidProperty(content) || (isValidProperty(content) && content.length <= 0))
						{
							addBlackList(workflowID, contentID);
						}
					});
				}
			}
			else
			{
				if (!found)
				{
					addBlackList(workflowID, contentID);
					callback('');
				}
			}
		}
	}
	
	// private ///////////////////////////////////////////////////////////////////
	
	function isBlackList(/*[String]*/ inWorkflowID, /*[String]*/ inContentID)
	{
		var ret = gIgnoreContentBlackList;

		if (!ret && isValidProperty(inContentID))
		{
			var workflowID = inWorkflowID;
		
			if (!isValidProperty(workflowID))
			{
				workflowID = 'no_workflow_content';
			}
			
			if (!isValidProperty(blacklist[workflowID]))
			{
				blacklist[workflowID] = {};
			}
			
			ret = isValidProperty(blacklist[workflowID][inContentID]);

			if (ret)
			{
				dbgLogContent("MultiContentStorage.isBlackList", inWorkflowID, inContentID, null, ret);
			}
		}
		
		return ret;
	}
	
	function addBlackList(/*[String]*/ inWorkflowID, /*[String]*/ inContentID)
	{
		if (isValidProperty(inContentID))
		{
			var workflowID = inWorkflowID;
		
			if (!isValidProperty(workflowID))
			{
				workflowID = 'no_workflow_content';
			}
			
			if (!isValidProperty(blacklist[workflowID]))
			{
				blacklist[workflowID] = {};
			}
			
			blacklist[workflowID][inContentID] = true;
		}
	}
	
	// initialize ////////////////////////////////////////////////////////////////
	
	function initialize()
	{
		forEach(inContentBasePaths, function(path)
		{
			localStorage.push(new LocalContentStorage(path));
		});
	}
	initialize();
}