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

WFRxPersistentTimerTest.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2022 Adobe
All Rights Reserved.

NOTICE: All information contained herein is, and remains
the property of Adobe and its suppliers, if any. The intellectual
and technical concepts contained herein are proprietary to Adobe
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.

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

	-- WF.core.self_test
local WFRxTestCase = require 'WFRxTestCase'

	-- WF.core.utils
local KSDate = require 'KSDate'
local WFRxPersistentTimer = require 'WFRxPersistentTimer'

	-- WF.oz_client.managed_catalog
local WFCatMockCatalog = require 'WFCatMockCatalog'

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

local createFakeWFCatalog = WFCatMockCatalog.createFakeWFCatalog

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

local WFRxPersistentTimerTest = {}

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

function WFRxPersistentTimerTest.rxTestResumePersistentTimer( rxTest )

	rxTest:setTimeLimit( 10 )

	local fakeWFCatalog = createFakeWFCatalog( rxTest )

	local docStore = fakeWFCatalog:docStore()

	local period = 0.5
	local periodBuffer = period / 5

	local fireCount = 0

	local obs = WFRxPersistentTimer( docStore, 'foo', period )
	
		:map( function()
		
			fireCount = fireCount + 1
			return fireCount
		
		end )
	
	local observer = rxTest:observe( obs )
	
	observer:expectData( 1 ) -- immediate response
	
	-- Sleep before the next emit, then cancel the timer.
	
	rxTest:sleep( period / 2 )
	
	observer:dispose()
	
	rxTest:expectEqual( 1, fireCount )
	
	-- Now create a new timer with the same identifier. This should resume execution.
	
	local startTime = KSDate.timeNow()
	
	local emitTimestamp
	
	observer = rxTest:observe( WFRxPersistentTimer( docStore, 'foo', period )
	
		:map( function()
		
			emitTimestamp = KSDate.timeNow()
			fireCount = fireCount + 1
			return fireCount
		
		end ) )
	
	-- Make sure the first timer event didn't arrive too early or too late:
	
	observer:expectDataWithinTime( period / 2 + periodBuffer, 2 ) -- Did it arrive too late?
	
	local delta = emitTimestamp - startTime
	
	rxTest:expectEqual( true, delta > period / 2 - periodBuffer ) -- Did it arrive too early?
	
	-- Make sure we get the next time event as well:
	
	observer:expectDataWithinTime( period + periodBuffer , 3 )

end

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

-- FIXME [jandrew 2025-03-11]: Disabled due to instability.

function WFRxPersistentTimerTest.DISABLED_rxTestUniqueIdentifiers( rxTest )

	rxTest:setTimeLimit( 10 )

	local fakeWFCatalog = createFakeWFCatalog( rxTest )

	local docStore = fakeWFCatalog:docStore()

	local period = 0.5

	local observer = rxTest:observe( WFRxPersistentTimer( docStore, 'foo', period ) )
	
	observer:expectData( true ) -- immediate response
	
	-- Sleep before the next emit, then cancel the timer.
	
	rxTest:sleep( period / 2 )
	
	observer:dispose()
	
	-- Now create a new timer with a different identifier. This should be a new timer.
	
	local startTime = KSDate.timeNow()
	local emitTimestamp
	
	observer = rxTest:observe( WFRxPersistentTimer( docStore, 'bar', period )
	
		:map( function()
		
			emitTimestamp = KSDate.timeNow()
			return true
		
		end ) )
	
	-- Make sure the first timer didn't arrive too late:
	
	observer:expectData( true )
	
	local delta = emitTimestamp - startTime
	
	rxTest:expectEqual( true, delta < 0.1 ) -- Did it arrive too late?

end

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

return WFRxTestCase.wrapSuite( 'WFRxPersistentTimerTest', WFRxPersistentTimerTest )
