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

HttpShutdownModel.lua

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

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

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

local Rx = require "Rx"
local WFRxHttpClient = require "WFRxHttpClient"

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

local logger = require "WFLogger"( "HttpShutdownModel" )

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

local function completionOnlyStream( desc, stream )

	-- this ensures the stream swallows any errors and data and only calls
	-- observer:onComplete()
	return stream
			:takeLast( 0 )
			:catch( 
				function( err )

					logger:warnf( "completionOnlyStream( %s ) error: %s", desc, err )

					return Rx.Observable.empty()

				end )

end

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

local function stopPixelProviderResultStream( pixelProviderProcessorStream )

	return pixelProviderProcessorStream
			:take( 1 )
			:flatMapLatest(
				function( pixelProviderProcessor )

					return pixelProviderProcessor:stop()

				end )

end

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

local _curlShutdownProcessingDelay = 1.0

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

local function make( pixelProviderProcessorStream )


	return {

		-- this observable emits true after running a series of async
		-- observers sequentially. 
		value = 
			Rx.Observable.concat(

				-- 1) wait for pixel provider stoppage so that it cancels in
				--    flight downloads and stops scheduling new ones
				completionOnlyStream( 
					"stopPixelProviderResultStream", 
					stopPixelProviderResultStream( 
						pixelProviderProcessorStream ) ),

				-- 2) if we have an info logger, log the active request count
				--    otherwise do nothing.
				logger.will_info and
					completionOnlyStream( 
						"WFRxHttpClient.activeRequestCount()", 
						WFRxHttpClient.activeRequestCount()
							:map(
								function( activeRequestCount )

									if activeRequestCount > 0 then

										logger:infof( "There were %s active requests before we started shutdown, delaying shutdown by %s seconds", 
															activeRequestCount, _curlShutdownProcessingDelay )

									end

								end ) ) or
					Rx.Observable.empty(),

				-- 3) stop any remaining http requests 
				completionOnlyStream( 
					"WFRxHttpClient.stopAllRequestsAndWait()", 
					WFRxHttpClient.stopAllRequestsAndWait(
						_curlShutdownProcessingDelay ) ),

				-- 4) emit true
				Rx.Observable.just( true )
					:tap( 
						function()

							logger:info( "HttpShutdownModel completed" )  

						end ) )

	}

end

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

return {

	make = make

}
