/***********************************************************************/
/*                                                                     */
/*                      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)
	{
		var workflowID = inWorkflowID;
		var contentID = inContentID;

		var job = null;

		if (isBlackList(workflowID, contentID))
		{
			job = new Job();
			job.setError("MultiContentStorage.getURL '" + workflowID + "' / '" + contentID + "' BLACKLIST");
			dbglogError(job.getError());
		}
		else
		{
			for (var index=0; index<localStorage.length ; index++)
			{
				var contentJob = localStorage[index].getURL(workflowID, contentID);
				if (contentJob.isStatus(IJob.STATUS_SUCCESS))
				{
					job = contentJob;
					dbgLogContent("MultiContentStorage.getURL", workflowID, contentID, 'success');
					break;
				}
			}

			if (!isValidProperty(job))
			{
				if (isValidProperty(remoteStorage))
				{
					var contentJob = remoteStorage.getURL(workflowID, contentID);
					job = new ProxyJob(contentJob, null, function (/*[any]*/ inError)
					{
						if (navigator.onLine)
						{
							// only put to black list if we're online
							addBlackList(workflowID, contentID);
						}
						dbgLogContent("MultiContentStorage.getURL", workflowID, contentID, inError);
						return inError;
					});
				}
				else
				{
					if (navigator.onLine)
					{
						// only put to black list if we're online
						addBlackList(workflowID, contentID);
					}
					job = new Job();
					job.setError("MultiContentStorage.getURL '" + workflowID + "' / '" + contentID + "' NOT exist");
					dbglogError(job.getError());
				}
			}
		}

		return job;
	}
 
	//////////////////////////////////////////////////////////////////////////////
	//
	// 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)
	{
		var workflowID = inWorkflowID;
		var contentID = inContentID;

		var job = null;

		if (isBlackList(workflowID, contentID))
		{
			job = new Job();
			job.setError("MultiContentStorage.getRaw '" + workflowID + "' / '" + contentID + "' BLACKLIST");
			dbglogError(job.getError());
		}
		else
		{
			for (var index=0; index<localStorage.length ; index++)
			{
				var contentJob = localStorage[index].getRaw(workflowID, contentID);
				if (contentJob.isStatus(IJob.STATUS_SUCCESS))
				{
					job = contentJob;
					break;
				}
			}

			if (!isValidProperty(job))
			{
				if (isValidProperty(remoteStorage))
				{
					var contentJob = remoteStorage.getRaw(workflowID, contentID);
					job = new ProxyJob(contentJob, null, function (/*[any]*/ inError)
					{
						if (navigator.onLine)
						{
							// only put to black list if we're online
							addBlackList(workflowID, contentID);
						}
						dbgLogContent("MultiContentStorage.getRaw", workflowID, contentID, inError);
						return inError;
					});
				}
				else
				{
					if (navigator.onLine)
					{
						// only put to black list if we're online
						addBlackList(workflowID, contentID);
					}
					job = new Job();
					job.setError("MultiContentStorage.getRaw '" + workflowID + "' / '" + contentID + "' NOT exist");
					dbglogError(job.getError());
				}
			}
		}

		return job;
	}
 
	//////////////////////////////////////////////////////////////////////////////
	//
	// Return content from string table
	//
	this.getString = function(/*[string]*/ inWorkflowID, /*[string]*/ inContentID)
	{
		var workflowID = inWorkflowID;
		var contentID = inContentID;

		var job = null;

		if (isBlackList(workflowID, contentID))
		{
			job = new Job();
			job.setError("MultiContentStorage.getString '" + workflowID + "' / '" + contentID + "' BLACKLIST");
			dbglogError(job.getError());
		}
		else
		{
			for (var index=0; index<localStorage.length ; index++)
			{
				var contentJob = localStorage[index].getString(workflowID, contentID);
				if (contentJob.isStatus(IJob.STATUS_SUCCESS))
				{
					var result = contentJob.getResult();

					if (isValidProperty(result) && result.length > 0)
					{
						job = contentJob;
						break;
					}
				}
			}

			if (!isValidProperty(job))
			{
				if (isValidProperty(remoteStorage))
				{
					var contentJob = remoteStorage.getString(workflowID, contentID);
					var job = new ProxyJob(contentJob, function(/*[any]*/ inResult)
					{
						if (!isValidProperty(inResult) || inResult.length == 0)
						{
							if (navigator.onLine)
							{
								// only put to black list if we're online
								addBlackList(workflowID, contentID);
							}
							dbgLogContent("MultiContentStorage.getString", workflowID, contentID, inResult);
						}

						return inResult;
					},
					function(/*[any]*/ inError)
					{
						if (navigator.onLine)
						{
							// only put to black list if we're online
							addBlackList(workflowID, contentID);
						}
						dbgLogContent("MultiContentStorage.getString", workflowID, contentID, inError);

						return inError;
					});
				}
				else
				{
					if (navigator.onLine)
					{
						// only put to black list if we're online
						addBlackList(workflowID, contentID);
					}
					job = new Job();
					job.setError("MultiContentStorage.getString '" + workflowID + "' / '" + contentID + "' NOT exist");
					dbglogError(job.getError());
				}
			}
		}

		return job;
	}
	
	// private ///////////////////////////////////////////////////////////////////
	
	function isBlackList(/*[String]*/ inWorkflowID, /*[String]*/ inContentID)
	{
		var ret = false;

		if (!gIgnoreContentBlackList && 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, 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();
}