--[[----------------------------------------------------------------------------

PixelProviderChooseBestPossibleLocalNegativePathTask.lua

--------------------------------------------------------------------------------

ADOBE CONFIDENTIAL
------------------
Copyright 2016 Adobe Systems Incorporated
All Rights Reserved.

NOTICE: All information contained herein is, and remain 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 may be covered by U.S. and Foreign
Patents, patents in process, and are protected by trade secret or copyright
law. Dissemination of this information or reproduction of this material is
strictly forbidden unless prior written permission is obtained from
Adobe Systems Incorporated.

------------------------------------------------------------------------------]]
	-- pixel provider
local PixelPathProviderStateMachine = require 'PixelPathProviderStateMachine'
local PixelProviderSharedBlobCache = require 'PixelProviderSharedBlobCache'

--------------------------------------------------------------------------------

local logger = require 'WFLogger'( 'PixelProviderChooseBestPossibleLocalNegativePathTask' )

--------------------------------------------------------------------------------

local WFArguments_check = require 'WFArguments'.check

--------------------------------------------------------------------------------

local function makeCheckForEquivalentRequests( equivalenceFunc )

	WFArguments_check( 'function' )

	return function( scheduler, localAssetId, ozBinaryType )

		local requests = 
				equivalenceFunc( scheduler, localAssetId, ozBinaryType )

		return #requests > 0

	end

end

--------------------------------------------------------------------------------

local canJoinPendingNegativeSave = 
		makeCheckForEquivalentRequests( 
			PixelProviderSharedBlobCache.getNeedNegativeSaveRequests )

--------------------------------------------------------------------------------

local canJoinInProgressNegativeSave = 
		makeCheckForEquivalentRequests( 
			PixelProviderSharedBlobCache.getActiveNegativeSaveRequests )

--------------------------------------------------------------------------------

local canJoinInProgressNegativeDownload = 
		makeCheckForEquivalentRequests( 
			PixelProviderSharedBlobCache.getActiveNegativeDownloadRequests )

--------------------------------------------------------------------------------

local PixelProviderSharedTaskUtils_renderInfoHasDownloadableProxy =
		assert( require "PixelProviderSharedTaskUtils".renderInfoHasDownloadableProxy,
			"PixelProviderSharedTaskUtils.renderInfoHasDownloadableProxy is missing!" )

--------------------------------------------------------------------------------

local PixelProviderSharedTaskUtils_getOriginalDownloadInfoFromRenderInfo =
		assert( require "PixelProviderSharedTaskUtils".getOriginalDownloadInfoFromRenderInfo,
			"PixelProviderSharedTaskUtils.getOriginalDownloadInfoFromRenderInfo is missing!" )

--------------------------------------------------------------------------------

local function chooseBestPossibleLocalNegativePath( request, scheduler,
													baseRenderInfoCache )

	local pixStreamId, localAssetId = unpack( request )

	local baseRenderInfo = baseRenderInfoCache:peekCacheItem( localAssetId )
	
	if type( baseRenderInfo ) ~= "table" then

		logger:warnf( "Can't choose best possible local negative path %s.%s: no baseRenderInfo",
						pixStreamId, localAssetId )

		-- force it to retrieve again
		return scheduler:_applyTransitionToRequest( 
							request, 'no_paths_available' )

	end
	
	if baseRenderInfo.originalPath then

		return scheduler:_applyTransitionToRequest( 
							request, 'have_local_original' )

	end
	
	if baseRenderInfo.proxyPath then

		return scheduler:_applyTransitionToRequest( 
							request, 'have_local_proxy' )

	end

	if canJoinPendingNegativeSave( scheduler, localAssetId, 'master' ) then

		return scheduler:_applyTransitionToRequest( 
							request, 'has_pending_original_save' )

	end

	if canJoinPendingNegativeSave( scheduler, localAssetId, 'proxy' ) then

		return scheduler:_applyTransitionToRequest( 
							request, 'has_pending_proxy_save' )

	end
	
	if canJoinInProgressNegativeSave( scheduler, localAssetId, 'master' ) then

		return scheduler:_applyTransitionToRequest( 
							request, 'has_active_original_save' )

	end
	
	if canJoinInProgressNegativeSave( scheduler, localAssetId, 'proxy' ) then

		return scheduler:_applyTransitionToRequest( 
							request, 'has_active_proxy_save' )

	end
	
	if canJoinInProgressNegativeDownload( scheduler, localAssetId, 'master' ) then

		return scheduler:_applyTransitionToRequest( 
							request, 'has_active_original_download' )

	end
	
	if canJoinInProgressNegativeDownload( scheduler, localAssetId, 'proxy' ) then

		return scheduler:_applyTransitionToRequest( 
							request, 'has_active_proxy_download' )

	end

	-- always download proxy first if we can. if both the proxy and the master
	-- are available on Oz, we will eventually hit the
	-- HaveProxyForBestPossibleLocalNegativePath and then transition to either
	-- downloading or passing the original path back to the UI

	if PixelProviderSharedTaskUtils_renderInfoHasDownloadableProxy( 
			baseRenderInfo ) then
	
		return scheduler:_applyTransitionToRequest( 
							request, 'try_download_proxy' )

	end


	if PixelProviderSharedTaskUtils_getOriginalDownloadInfoFromRenderInfo( 
			baseRenderInfo ) then
		
		return scheduler:_applyTransitionToRequest( 
							request, 'try_download_original' )
											
	end

	return scheduler:_applyTransitionToRequest( request, 'no_paths_available' )

end

--------------------------------------------------------------------------------

local function processRequests( scheduler, baseRenderInfoCache )

	scheduler:_mapAllRequestsWithState( 
		PixelPathProviderStateMachine.LocalBinaryPathCheckStates.ChooseBestPossibleLocalNegativePath,
			chooseBestPossibleLocalNegativePath, 
				scheduler, baseRenderInfoCache )


end

--==============================================================================

return {

	processRequests = processRequests,

}
