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

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.

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

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

	-- WF.core.utils
local WFAnalytics = require 'WFAnalytics'
local WFLogger = require "WFLogger"
local WFRxRunUntilDone = require 'WFRxRunUntilDone'

	-- WF.oz_client.manged_catalog
local WFCatAssetAux = require 'WFCatAssetAux'

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

local logger = WFLogger( 'LriDevelopModel' )

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

local runUntilDone = WFRxRunUntilDone

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

local LriDevelopModel = {}

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

local function lockAsset( ozCatalogService, assetId )

	logger:infof( "Protecting asset from WF background operations: %s", assetId )

	ozCatalogService:getSyncClient():lockAssets( { assetId } ):call( runUntilDone )

end

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

local function unlockAsset( ozCatalogService, assetId )

	logger:infof( "Removing protection from WF background operations: %s", assetId )

	ozCatalogService:getSyncClient():unlockAssets( { assetId } ):call( runUntilDone )

end

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

local function applyDevelopChanges( ozCatalogService, assetId, overlay, auxInfo )

	logger:infof( "Apply develop changes for asset: %s", assetId )

	return ozCatalogService:getWfCatalog()

		:take( 1 )

		:flatMap( function( wfCatalog )

			local docStore = wfCatalog:docStore()

			local auxDataList =  auxInfo or {}

			return WFCatAssetAux.getAuxOverlay( wfCatalog, assetId, auxDataList )

				:map( function( auxOverlay )

					local mergedOverlay = WFCatAssetAux.mergeAuxOverlay( overlay, auxOverlay )

					mergedOverlay._id = assetId

					return mergedOverlay

				end )

				:flatMap( function( mergedOverlay )

					return docStore:applyOverlay( mergedOverlay )

				end )
				:tapOnError( function( errMsg )

					local event = {
						['event.type'] = 'error',
						['event.subtype'] = 'developModel-applyOverlay-error',
						['event.appWorkflow'] = 'develop',
						['content.id'] = assetId,
						['event.error_desc'] = errMsg
					}

					WFAnalytics.trackEvent( event )

				end )
		end )

end

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

function LriDevelopModel.makeModel( ozCatalogService, assetId, optImageType )

	lockAsset( ozCatalogService, assetId )
	
	local value = WFCatAssetAux.ozCatalogService_ensureAuxFilesExistLocally_Mobile( ozCatalogService, assetId, optImageType )
		:concat( Observable.never() ) -- Prevent the model from closing prematurely

	return {

		assetId = assetId,
		catalog = ozCatalogService,
		value = value,

		models = {

			downloadLatestAuxFiles = function( self, optImageType )

				return {
					value = WFCatAssetAux.ozCatalogService_ensureAuxFilesExistLocally_Mobile( ozCatalogService, assetId, optImageType )
				}

			end,

			applyChanges = function( self, overlay, auxInfo )

				return {
					value = applyDevelopChanges( ozCatalogService, assetId, overlay, auxInfo )
				}

			end

		},

		close = function( self )
			unlockAsset( ozCatalogService, assetId )
		end,

	}

end

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

return LriDevelopModel
