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

WFCatPendingUpdates.lua

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

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.

----------------------------------------------------------------------------]]--
	-- rx
local Rx = require "Rx"

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

local WFCatPendingUpdates = {}
local _pendingAssetIdUpdatesMap = {}
local _fieldKeyAssetIdMap = {}
local _hasPendingUpdatesStream = Rx.BehaviorSubject( false )

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

--[[!
	\brief Registers an update for an asset and field.

	\param assetId
	\param fieldKey (string) Unique identifier for the field/tag
	\param valueKey (string) Unique identifier for the value.
	\param value (any) value which can be stored and retrieved later.
		For eg., valueKey can have the actual keyword, and value might
		have the timestamp as well.
	\param isDelete (boolean) Whether this update is a deletion.

--]]

function WFCatPendingUpdates.addToPendingUpdates( assetId, fieldKey, valueKey, value, isDelete )
	local changeList = _pendingAssetIdUpdatesMap[ assetId ] or {}
	
	local fieldChangeList = changeList[ fieldKey ] or {}
	local currValueUpdate = fieldChangeList[ valueKey ]
	 
	local assetsChangedForField = _fieldKeyAssetIdMap[ fieldKey ] or {}
	if currValueUpdate and ( currValueUpdate.isDelete ~= isDelete ) then
		-- Conflicting actions. Remove both.
		fieldChangeList[ valueKey ] = nil
		local updateCount = assetsChangedForField[ assetId ] - 1
		assetsChangedForField[ assetId ] = ( updateCount > 0 ) and updateCount or nil
	else
		fieldChangeList[ valueKey ] = { value = value, isDelete = isDelete }
		assetsChangedForField[ assetId ] = ( assetsChangedForField[ assetId ] or 0 ) + 1
	end
	
	changeList[ fieldKey ] = fieldChangeList
	_pendingAssetIdUpdatesMap[ assetId ] = changeList
	_fieldKeyAssetIdMap[ fieldKey ] = assetsChangedForField

end

--------------------------------------------------------------------------------
--[[!
	\brief Removes a previously registered update

	\param assetId
	\param fieldKey (string) Unique identifier for the field/tag
	\param valueKey (string) Unique identifier for the value.

--]]
function WFCatPendingUpdates.removeFromPendingUpdates( assetId, fieldKey, valueKey )
	local changeList = _pendingAssetIdUpdatesMap[ assetId ] or {}
	
	local fieldChangeList = changeList[ fieldKey ] or {}
	fieldChangeList[ valueKey ] = nil
	
	local assetsChangedForField = _fieldKeyAssetIdMap[ fieldKey ] or {}
	local updateCount = assetsChangedForField[ assetId ] - 1
	assetsChangedForField[ assetId ] = ( updateCount > 0 ) and updateCount or nil
	
	changeList[ fieldKey ] = fieldChangeList
	_pendingAssetIdUpdatesMap[ assetId ] = changeList
	_fieldKeyAssetIdMap[ fieldKey ] = assetsChangedForField
	 
end

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

function WFCatPendingUpdates.getPendingUpdatesForAsset( assetId, fieldKey )
	local changeList = _pendingAssetIdUpdatesMap[ assetId ] or {}
	local updates = changeList[ fieldKey ] or {}
	
	return updates
	
end

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

function WFCatPendingUpdates.getUpdatePendingAssetsForField( fieldKey )
	return _fieldKeyAssetIdMap[ fieldKey ]
	
end

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

function WFCatPendingUpdates.getAllPendingUpdates( )
	return _pendingAssetIdUpdatesMap
	
end

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

function WFCatPendingUpdates.pendingUpdatesTriggerStream()
	return _hasPendingUpdatesStream
end

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

function WFCatPendingUpdates.triggerPendingUpdatesStream()
	_hasPendingUpdatesStream:onNext( true )
end

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

return WFCatPendingUpdates
