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

WFCatImportManifestMessages.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2017 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 Subject = Rx.Subject

local WFTableArchiving = require 'WFTableArchiving'

	-- WF.core.logging
local WFLogger = require 'WFLogger'

	-- WF.oz_client.managed_catalog.import
local WFCatImportManifestConstants = require 'WFCatImportManifestConstants'

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

local logger = WFLogger 'WFCatImportManifestMessages'

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

local kProgressGranularity = 0.01

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

local WFCatImportManifestMessages = {
	_messageSink = false,
		-- Subject that sends formatted messages
		
	_progressComplete = false,
		-- Tracks the overall progress of all clients
		
	_totalWork = false,
		-- The total absolute work we expect to do
		
	_progressInfo = false,
		-- Container for the progress info for each client
}

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

function WFCatImportManifestMessages:__init()
	
	self._messageSink = Subject()
	self._totalWork = 0
	self._progressComplete = 0
	self._progressInfo = {}
end

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

function WFCatImportManifestMessages:registerStage( stageName, weight )
	self._progressInfo[ stageName ] = {
		weight = weight,
		percentComplete = 0,
	}
	
	self._totalWork = self._totalWork + weight
end

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

function WFCatImportManifestMessages:updateProgress( stageName, percentComplete, forceSend )
	
	local progressInfo = self._progressInfo[ stageName ]
	
	if forceSend or math.abs( progressInfo.percentComplete - percentComplete ) > kProgressGranularity then
		self._progressInfo[ stageName ].percentComplete = percentComplete
		
		-- Aggregate the progress
		local progressComplete = 0
		for _, info in pairs( self._progressInfo ) do
			progressComplete = progressComplete + info.weight * info.percentComplete
		end
		
		progressComplete = progressComplete / self._totalWork
		
		-- Report the progress if its worth it
		if forceSend or math.abs( self._progressComplete - progressComplete ) > kProgressGranularity then
			
			self._messageSink:onNext( {
				messageType = WFCatImportManifestConstants.messageTypes.progress,
				body = {
					curStage = stageName,
					progressComplete = progressComplete,
				},
			} )
			
			self._progressComplete = progressComplete
		end
	end
end

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

function WFCatImportManifestMessages:sendMessage( messageBody )
	self._messageSink:onNext( {
		messageType = WFCatImportManifestConstants.messageTypes.message,
		body = messageBody,
	} )
end

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

function WFCatImportManifestMessages:sendStatus( statusInfo )
	self._messageSink:onNext( {
		messageType = WFCatImportManifestConstants.messageTypes.status,
		body = statusInfo,
	} )
end

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

function WFCatImportManifestMessages:sendSummary( dataType, successCount )
	self._messageSink:onNext( {
		messageType = WFCatImportManifestConstants.messageTypes.summary,
		body = {
			dataType = dataType,
			migrated = successCount,
		},
	} )
end

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

function WFCatImportManifestMessages:messages()
	return self._messageSink
		
		:tap( function( msg )
			
			local msgStr = type( msg ) == 'table' and WFTableArchiving.tableToString( msg )
				or tostring( msg )
			logger:debugf( "MigMessage: %s", msgStr )
		end )
		
		:tapOnCompleted( function()
			
			logger:infof( "MigMessage: Message Stream Completed" )
		end )
end

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

function WFCatImportManifestMessages:shutdown()
	self._messageSink:onCompleted()
end

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

return Rx.Class 'WFCatImportManifestMessages'( WFCatImportManifestMessages )
