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

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

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

	-- WF.core.reactive
local KSReactive = require "KSReactive"

	-- WF.core.utils
local KSTableUtils = require 'KSTableUtils'
local WFUnknown = require 'WFUnknown'
local WFArguments = require 'WFArguments'

	-- WF.oz_client.sync_engine
local WFOzSyncConstants = require 'WFOzSyncConstants'

	-- WF.lrmobile
local LrmAssetUtils = require 'LrmAssetUtils'

local OzCatalogUploadStatus = require "OzCatalogUploadStatus"

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

local derefOpt = assert( KSTableUtils.derefOpt )

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

local LrmAssetInfoModel = {}
local Model = {}

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

local function getAssetInfo( catalog, assetInfo, userId, binaryPreference )

	assert( binaryPreference, 'binaryPreference needs to be passed in' )
	
	if not assetInfo then
		return nil
	end

	local localOnly = assetInfo._localOnly or {}
	local asset = {}

	asset.revisionId = assetInfo._revId
	asset.width = derefOpt( assetInfo, "importSource", "originalWidth" )
	asset.height = derefOpt( assetInfo, "importSource", "originalHeight" )
	asset.captureDate = assetInfo.captureDate
	asset.fileName = derefOpt( assetInfo, "importSource", "fileName" )
	asset.canDevelop = LrmAssetUtils.hasProxy( assetInfo ) or LrmAssetUtils.hasMaster( assetInfo )
	asset.xmp = LrmAssetUtils.getXmp( assetInfo )
	asset.hasThumbnailLocally = LrmAssetUtils.hasThumbnailLocally( assetInfo )
	asset.hasPreviewLocally = LrmAssetUtils.hasPreviewLocally( assetInfo )
	asset.hasMasterLocally = LrmAssetUtils.hasMasterLocally( assetInfo )
	asset.hasProxyLocally = LrmAssetUtils.hasProxyLocally( assetInfo )
	asset.hasMasterOnOz = LrmAssetUtils.hasMasterOnOz( assetInfo )
	asset.originalIsValid = OzCatalogUploadStatus.assetOriginalIsValid( assetInfo )
	
	asset.croppedWidth = derefOpt( assetInfo, "develop", "croppedWidth" )
	asset.croppedHeight = derefOpt( assetInfo, "develop", "croppedHeight" )
	asset.xmpCameraRaw = derefOpt( assetInfo, "develop", "xmpCameraRaw" )
	asset.userOrientation = derefOpt( assetInfo, "develop", "userOrientation" )
	asset.isVideo = LrmAssetUtils.isVideo( assetInfo )
	asset.contentTypeNumber = LrmAssetUtils.getContentTypeNumber( assetInfo )
	asset.binaryPreference = LrmAssetUtils.preferableBinaryForDevelop( assetInfo, binaryPreference )
	asset.contentType = derefOpt( assetInfo, "importSource", "contentType" )
	asset.title = derefOpt( assetInfo, 'xmp', 'dc', 'title' )
	asset.caption = derefOpt( assetInfo, 'xmp', 'dc', 'description' )
	
	if type( asset.xmpCameraRaw ) == 'table' then
	
		asset.localXmpDevelopPath = derefOpt( localOnly, 'files', 'xmp_develop', 'path' )

	end

	local thumbnailRevision = LrmAssetUtils.getRenditionRevision( assetInfo, 'thumbnail2x' )
	local customFields = derefOpt( localOnly, 'lrm_customData' )
	if customFields and type( customFields ) == 'table' then
		for k, v in pairs( customFields ) do
			if v.isValidForCurrentRevision and v.currentRevision ~= thumbnailRevision then
				customFields[ k ] = nil
			end
		end
	end
	
	asset.customFields = customFields
	
	asset.flag = 'unflagged'
	
	local reviews = derefOpt( assetInfo, 'reviews' )
	if reviews and type( reviews ) == 'table' then
		asset.flag = derefOpt( reviews, userId, 'flag' )
			or derefOpt( reviews, WFOzSyncConstants.kGlobalDocumentId, 'flag' )
			or asset.flag
	end
	
	asset.rating = 0
	
	local ratings = KSTableUtils.derefOpt( assetInfo, 'ratings' )
	if ratings and type( ratings ) == 'table' then
		asset.rating = derefOpt( ratings, userId, 'rating' )
			or derefOpt( ratings, WFOzSyncConstants.kGlobalDocumentId, 'rating' )
			or asset.rating
	end
	
	return asset
end

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

function Model:assetInfo()

	self.isReceivingUpdates = true
	
	local catalog = self.catalog
	local assetInfoB = catalog
		:ozUserIdP()
		:untilResolvedB( 'data', WFUnknown.value() )
		:closingKnownMapSwitchB( function( userId )
		
			return catalog
				:photoInfoB( self.assetId )
				:closingKnownMapB( function( assetInfo )
				
					return getAssetInfo( catalog, assetInfo, userId, self.binaryPreference )
					
				end )
		end )
		
	return {
		valueB = assetInfoB,
	}
end

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

function LrmAssetInfoModel.makeModel( catalog, assetId, binaryPreference )
	
	WFArguments.check( 'table', 'string', 'binaryStrategy' )
	
	local resultB = KSReactive.variableB( nil )
	
	local model = {
		isReceivingUpdates = false,
		assetId = assetId,
		catalog = catalog,
		binaryPreference = binaryPreference,
		
		valueB = resultB,
		models = Model,
	}

	catalog
		:photoInfoP( assetId )
		:mapDataP_new( function( docValue )
		
			return catalog:ozUserIdP()
				:mapDataP_new( function( userId )
				
					return docValue, userId
					
				end )
		end )
		:whenResolvedDo( function( status, docValue, userId )
		
			if status == 'data' and not model.isReceivingUpdates then
			
				resultB:set( getAssetInfo( catalog, docValue, userId, binaryPreference ) )
				
			end
		end )
		:attachTo( resultB )
	
	return model
end

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

return LrmAssetInfoModel
