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

WFCatSharedWithYouUtils.lua

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

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

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

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

	-- WF.oz_client.managed_catalog
local WFCatAssetUtils = require 'WFCatAssetUtils'
local WFCatFileSpec = require 'WFCatFileSpec'

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

local check = assert( WFArguments.check )

local KSTableUtils_derefOpt = assert( KSTableUtils.derefOpt )

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

-- @mark WFCatSharedWithYouUtils namespace

local WFCatSharedWithYouUtils = {}

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

--[[!
	\brief Check whether the current user is allowed to edit an asset according to these rules:
	
		If _serverProvidedMetadata exists, you can edit when there's master link and editable flag
		If _serverProvidedMetadata does not exist, you can edit when master/proxy exists locally

	\param docValue The whole doc value of the asset
		
	\return (boolean) Returns true if the asset can be edited by current user
--]]

function WFCatSharedWithYouUtils.canEditAsset( docValue )

	check( 'table' )

	local assetSpaceId = docValue._spaceId
	
	if not assetSpaceId then
		return true
	end
	
	local serverProvidedMetadata = KSTableUtils_derefOpt( docValue, '_serverProvidedMetadata' )
	
	local hasOriginalLocally = WFCatAssetUtils.hasLocalOriginal( docValue )
	local hasProxyLocally = WFCatAssetUtils.hasLocalProxy( docValue )
	
	if serverProvidedMetadata then
	
		local originalLink = WFCatFileSpec.getOriginalLinkFromDocValue( docValue )
		local proxyLink = WFCatFileSpec.getProxyLinkFromDocValue( docValue )

		local editable = KSTableUtils_derefOpt( docValue, '_serverProvidedMetadata', 'editable' )
		
		return not not ( editable and ( originalLink or proxyLink or hasOriginalLocally or hasProxyLocally ) )
	
	else
	
		return hasOriginalLocally or hasProxyLocally
		
	end

end

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

--[[!
	\brief Check whether the current user is allowed to delete an asset according to these rules:
		If an asset is not from the spaces feed, you can delete it (it's from your own catalog)
		If the asset has been imported by someone else, you cannot delete it
		If the asset has been imported more than 2 days ago, you cannot delete it

	\param docValue The whole doc value of the asset
		
	\return (boolean) Returns true if the asset has been added by the current
		user and is within the deletion window
--]]

function WFCatSharedWithYouUtils.canDeleteAsset( docValue )

	check( 'table' )

	local assetSpaceId = docValue._spaceId
	
	if not assetSpaceId then
		return true
	end
	
	local isAssetOwner = not KSTableUtils_derefOpt( docValue, '_serverProvidedMetadata', 'importedByUser', 'id' )
		-- importedByUser ID is never set for images uploaded by the user.

	local currentTimestamp = KSDate.timeInIso8601Format()
		
	local uploadedTimestamp = KSTableUtils_derefOpt( docValue, '_serverProvidedMetadata', 'created' )
			or currentTimestamp
			-- If the created date isn't set, the image hasn't been uploaded yet.

	local differenceInSeconds = KSDate.differenceInSeconds( uploadedTimestamp, currentTimestamp )

	local deletionWindowInHours = 48		
	local deletionWindowInSeconds = deletionWindowInHours * 60 * 60
	
	return not not ( isAssetOwner and
		differenceInSeconds < deletionWindowInSeconds )

end

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

--[[!
	\brief Check whether the current user is allowed to delete the specified assets.

	\param wfCatalog (WFCatalog)
	\param arrayOfDocIds (table) An array of asset doc IDs.
		
	\return (table) A table containing the asset IDs that can be deleted.
--]]

function WFCatSharedWithYouUtils.canDeleteAssetIds( wfCatalog, arrayOfDocIds )

	check( 'WFCatalog', 'table' )

	return wfCatalog:docStore():bulkDocValue( arrayOfDocIds )
	
		:map( function( arrayOfDocValues )
	
			local canDeleteDocIds = {}
			
			for _, docValue in ipairs( arrayOfDocValues ) do
			
				local canDelete = WFCatSharedWithYouUtils.canDeleteAsset( docValue )
			
				if canDelete then
					canDeleteDocIds[ #canDeleteDocIds + 1 ] = docValue._id
				end
			
			end
			
			return canDeleteDocIds

		end )

end

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

--[[!
	\brief Estimate the required space on disk required to contribute a list of assets

	\param wfCatalog (WFCatalog)
	\param arrayOfDocIds (table) An array of asset doc IDs.
		
	\return number An estimate of the required space on disk required to contirbute the input
		assets. This is right now a *very* conservative estimate since WF may actually copy
		all originals while making a copy of the asset while contributing.
--]]

function WFCatSharedWithYouUtils.spaceNeededToContributeAssets( wfCatalog, arrayOfDocIds )

	check( 'WFCatalog', 'table' )

	return wfCatalog:docStore():bulkDocValue( arrayOfDocIds )
	
		:map( function( arrayOfDocValues )
	
			local totalSize = 0
			
			for _, docValue in ipairs( arrayOfDocValues ) do
			
				local fileSize = KSTableUtils_derefOpt( docValue, 'importSource', 'fileSize' ) or 0
				
				totalSize = totalSize + fileSize
						
			end
			
			return totalSize

		end )

end

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

--[[!
	\brief Checks whether the current user is the owner of the asset

	\param docValue The whole doc value of the asset
		
	\return (boolean) Returns true if the asset is owned by the current user
--]]

function WFCatSharedWithYouUtils.isAssetOwner( docValue )

	check( 'table' )

	local assetSpaceId = docValue._spaceId
	
	-- if the asset doc has space id, that means, it 
	-- was synced as part of space sync feed
	return not assetSpaceId

end

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

return WFCatSharedWithYouUtils
