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

WFRequestTestHandler.lua

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

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

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

	-- RxLua
local Rx = require 'Rx'
local Observable = Rx.Observable

	-- WF.core.lua
local KSData = require 'KSData'

	-- WF.core.lua.threading
local WFRequestDispatcher = require 'WFRequestDispatcher'
local WFTimer = require 'WFTimer'

	-- WF.core.reactive
local KSPromises = require 'KSPromises'
local KSReactive = require 'KSReactive'

	-- WF.core.rxlua
local WFRxScheduler = require 'WFRxScheduler'


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

local testTargetClass = Rx.Class 'testTargetClass' {

	doSomething = function( self, value )
		return "did something", value + 42
	end,

}

local testTargetObject = testTargetClass()

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

local processorId

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

WFRequestDispatcher.enableDiagnosticLogForRequestStats()

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

WFRequestDispatcher.onMessage( 'getProcessorId', function( ... )

	return processorId, ...

end )

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

WFRequestDispatcher.onMessage( 'getInstalledMessages', function()

	return WFRequestDispatcher.getInstalledMessages()

end )

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

WFRequestDispatcher.onMessageDo {

	message = 'doSomethingWithTargetObject',
	method = 'doSomething',
	target = testTargetObject,

}

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

WFRequestDispatcher.onMessage( 'returnNothing', function()

end )

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

WFRequestDispatcher.onMessage( 'echo', function( ... )

	return select( '#', ... ), ...

end )

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

WFRequestDispatcher.onMessage( 'echoDelay', function( interval, str )

	return WFTimer.afterDelayP( interval )
		:mapDataP( function()
		
			return 'data', str
		
		end )

end )

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

local lastRequestId

WFRequestDispatcher.onMessage( 'delayAndWatchForCancel', function( interval, requestId )

	lastRequestId = requestId

	return WFTimer.afterDelayP( interval )
		:mapDataP( function()
		
			lastRequestId = "FINISHED:" .. requestId
			return 'data', requestId
		
		end )

end )

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

WFRequestDispatcher.onMessage( 'didPreviousDelayGetCanceled', function()

	return lastRequestId

end )

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

WFRequestDispatcher.onMessage( 'sendError', function( message )

	return KSPromises.resolvedPromiseP( 'error', message )

end )

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

WFRequestDispatcher.onMessage( 'sendValueThenError', function( message )

	local counter = 0

	return KSReactive.timedSeqB( 'data', 1, 'error' )
		:closingRawMapB( function( _, status )

			counter = counter + 1

			return status, counter
		
		end )

end )

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

WFRequestDispatcher.onMessage( 'sendImmediateErrorViaEventStream', function( message )

	return KSReactive.constantErrorB( message )

end )

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

WFRequestDispatcher.onMessage( 'sendNothing', function()

	return KSReactive.zeroE()

end )

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

local mostRecentKSData = nil

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

WFRequestDispatcher.onMessage( 'deferredCloseThis', function( value )

	WFRequestDispatcher.deferredClose( value )
	
	return value

end )

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

WFRequestDispatcher.onMessage( 'sendDataWithDeferredClose', function( str )

	mostRecentKSData = KSData.make( str )
	
	WFRequestDispatcher.deferredClose( mostRecentKSData )
	
	return mostRecentKSData

end )

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

WFRequestDispatcher.onMessage( 'didClosePreviousData', function( str )

	if mostRecentKSData then
		return mostRecentKSData:isClosed()
	else
		error 'no recent data to check'
	end

end )

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

WFRequestDispatcher.onMessage( 'setPref', function( k, v )

	local KSPrefs = require "KSPrefs"
	KSPrefs[ k ] = v

end )

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

WFRequestDispatcher.onMessage( 'collectgarbage', function( k, v )

	collectgarbage 'collect'
	collectgarbage 'collect'
	collectgarbage 'collect'

end )

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

WFRequestDispatcher.onMessage( 'counterE', function( start, stop )

	local resultE = KSReactive.sourceE()
	
	local counter = start
	
	local WFTimer = require 'WFTimer'
	
	local function bumpCounterAndSend()
	
		WFTimer.afterDelayDo( .1, function()

			if counter <= stop then
				resultE:post( counter )
				bumpCounterAndSend()
			else
				resultE:close()
			end

			counter = counter + 1
			
		end )
	
	end
	
	bumpCounterAndSend()
	
	return resultE

end )

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

WFRequestDispatcher.onMessage( 'observableEmpty', function()

	return Observable.empty()

end )

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

WFRequestDispatcher.onMessage( 'observableEcho', function( ... )

	return Observable.just( select( '#', ... ), ... )

end )

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

WFRequestDispatcher.onMessage( 'observableTimedSequence', function( limit )

	return Observable.interval( .125, WFRxScheduler.sharedScheduler() ):take( limit )

end )

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

WFRequestDispatcher.onMessage( 'observableSendValueThenError', function()

	return Observable.timer( 0, 1, WFRxScheduler.sharedScheduler() )
		:map( function( seq )
			
			if seq == 1 then
				return 1
			else
				error "2"
			end
		
		end )
	
end )

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

WFRequestDispatcher.onMessage( 'observableDelayAndWatchForCancel', function( interval, requestId )

	lastRequestId = requestId

	return Observable.timer( interval, WFRxScheduler.sharedScheduler() )
		:map( function()

			lastRequestId = "OBSERVABLE FINISHED:" .. requestId
			return lastRequestId
		
		end )

end )

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

WFRequestDispatcher.onMessage( 'DEBUG_dumpCoverageP', function( path )

	require 'SetupCoverage'.dumpCoverage( path )

	return true

end )

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

return {
	initMessageProcessor = function( inProcessorId )
		processorId = inProcessorId
	end,
}
