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

NmbDocValueToRenderInfoStream.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2015 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.

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

NmbDocValueToRenderInfoStream consumes a sequence of array-valued tables of asset IDs
and reports the "render info" of each corresponding document either as it first
appears in the array, or as it changes in value while still in the array.

Asset IDs may be either numeric (local) or string (global) document IDs.

Render info is expressed as a table similar to the following:

	{
		_id = "(uuid / global ID)",
		_localId = (number),
		originalPath = "(path)",
		proxyPath = "(path)",
		develop = {
			-- develop settings as from Oz (http://belt.sea.adobe.com/asset/develop.html)
		}
	}

------------------------------------------------------------------------------]]

	-- WF.core.utils
local KSTableUtils = require 'KSTableUtils'
local WFFunctionUtils = require 'WFFunctionUtils'

	-- WF.oz_client.managed_catalog.develop
local NmbDocValueToRenderInfo = require "NmbDocValueToRenderInfo"

	-- pixel provider
local WFCatRenderCapabilities = require 'WFCatRenderCapabilities'

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

local WFFunctionUtils_reduce = assert( WFFunctionUtils.reduce,
			"WFFunctionUtils.reduce does not exist" )

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

local KSTableUtils_mapArrayToSet = assert( KSTableUtils.mapArrayToSet,
			"KSTableUtils.mapArrayToSet does not exist" )

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

local NmbDocValueToRenderInfo_maybeExtractRenderInfoFromDocValue =
		assert( 
			NmbDocValueToRenderInfo.maybeExtractRenderInfoFromDocValue,
			"NmbDocValueToRenderInfo.maybeExtractRenderInfoFromDocValue missing" )

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

local NmbDocValueToRenderInfo_extractRenderInfoFromDocValue =
		assert( 
			NmbDocValueToRenderInfo.extractRenderInfoFromDocValue,
			"NmbDocValueToRenderInfo.extractRenderInfoFromDocValue missing" )

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

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

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

local function extractRenderInfoOrReportFailure( packedRenderInfosResults, 
													docValue )

	local renderInfos, missingRenderInfoIds =
			packedRenderInfosResults[ 1 ], packedRenderInfosResults[ 2 ]

	local maybeRenderInfo = 
		NmbDocValueToRenderInfo_maybeExtractRenderInfoFromDocValue( docValue )

	if maybeRenderInfo then

		renderInfos[ #renderInfos + 1 ] = maybeRenderInfo

	else

		missingRenderInfoIds[ #missingRenderInfoIds + 1 ] = docValue._localId

	end

	return packedRenderInfosResults

end

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

local function extractRenderInfos( docValues )

	local packedRenderInfosResults = { {}, {} }
	
	return unpack( WFFunctionUtils_reduce( 
						packedRenderInfosResults,
						extractRenderInfoOrReportFailure, docValues ) )

end

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

local function renderInfoStream( docStore, localAssetIds )

	if logger.will_info then

		logger:infof( "Calling bulkDocValue on { %s }",  
						table.concat( localAssetIds, ", " ) )

	end

	local origAssetIdCount = #localAssetIds

	local renderInfosStream = 
			docStore
				:bulkDocValue( localAssetIds, nil, "renderInfoStream" )
				:map( extractRenderInfos )

	return logger.will_info and
			renderInfosStream	
				:tap(
					function( renderInfos, missingRenderInfoIds )

						logger:infof( "Got %s render infos and %s errorIds after requesting %s",  
										#renderInfos, #missingRenderInfoIds, origAssetIdCount )

					end ) or
			renderInfosStream

end

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

local function maybeReportRenderInfoUpdate( watchedLocalAssetIdsSet, docValue )

	local localAssetId = docValue._localId 

	if not localAssetId then

		return watchedLocalAssetIdsSet

	end

	if not WFCatRenderCapabilities.isRenderableAsset( docValue ) then

		return watchedLocalAssetIdsSet

	end

	if not watchedLocalAssetIdsSet[ localAssetId ] then

		return watchedLocalAssetIdsSet

	end

	-- TODO we could improve performance by saving render info
	-- in watchedLocalAssetIdsSet when it is generated then
	-- compare it with a previous value.
	return watchedLocalAssetIdsSet, { NmbDocValueToRenderInfo_extractRenderInfoFromDocValue( docValue ) }

end

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

local function changedRenderInfoStream( docStore, localAssetIds )

	local watchedLocalAssetIdsSet = KSTableUtils_mapArrayToSet( localAssetIds )

	return docStore
			:scannedFilteredMappedChangesFeed( 
				"NmbDocValueToRenderInfoStream", "maybeReportRenderInfoUpdate",
				watchedLocalAssetIdsSet )

end

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

return {

	renderInfoStream = renderInfoStream,

	changedRenderInfoStream = changedRenderInfoStream,

	maybeReportRenderInfoUpdate = maybeReportRenderInfoUpdate,

}
