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

WFCatSharedWithYouAlbumsTest.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.self_test
local WFRxTestCase = require 'WFRxTestCase'

	-- WF.core.utils
local KSDate = require 'KSDate'
local KSIdGenerator = require 'KSIdGenerator'
local KSTableUtils = require 'KSTableUtils'
local WFPlatformInfo = require 'WFPlatformInfo'

	-- WF.managed_catalog
local WFCatAssetTestUtils = require 'WFCatAssetTestUtils'
local WFCatMockCatalog = require 'WFCatMockCatalog'
local WFCatSharedWithYouUtils = require 'WFCatSharedWithYouUtils'

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

local WFCatMockCatalog_createFakeWFCatalog = assert( WFCatMockCatalog.createFakeWFCatalog )

local KSTableUtils_setNested = assert( KSTableUtils.setNested )

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

local function createFakeWFCatalog( rxTest, expectedRequestResponse )

	local optArgs = {}
	
	if WFPlatformInfo.isMobile() then
		optArgs.indexDefinitions = 'LrmCatalogIndexDefinitions.lua'
	end

	return WFCatMockCatalog_createFakeWFCatalog( rxTest, nil, expectedRequestResponse, optArgs )
	
end

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

local WFCatSharedWithYouUtilsTest = {}

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

function WFCatSharedWithYouUtilsTest.rxTestAssetCanBeEdited( rxTest )

	rxTest:setTimeLimit( 10 )
	
	local wfCatalog = createFakeWFCatalog( rxTest )
	
	local function createCanDeleteObservable( assetId )
		return wfCatalog:docStore()
			:docValue( assetId )
			:map( WFCatSharedWithYouUtils.canEditAsset )
	end
	
	-- check asset it's owner catalog
	
	local assetId1 = KSIdGenerator.uuidInLowercaseHex()
	local assetDoc1 = WFCatAssetTestUtils.createAssetDocument( rxTest, wfCatalog, assetId1 )
	
	rxTest:expectSingleValue( wfCatalog:docStore():setDocValue( assetDoc1 ), ':ignore:' )
	
	rxTest:expectSingleValue( createCanDeleteObservable( assetId1 ), true )
	
	-- check asset if it's in space with local binary, but no oz data
	
	local spaceId = KSIdGenerator.uuidInLowercaseHex()
	
	local assetId2 = KSIdGenerator.uuidInLowercaseHex()
	local assetDoc2 = WFCatAssetTestUtils.createAssetDocument( rxTest, wfCatalog, assetId2 )
	assetDoc2._spaceId = spaceId
	assetDoc2._serverProvidedMetadata = nil
	
	rxTest:expectSingleValue( wfCatalog:docStore():setDocValue( assetDoc2 ), ':ignore:' )
	
	rxTest:expectSingleValue( createCanDeleteObservable( assetId2 ), true )
	
	-- check asset if it's in space with local binary, oz editable flag, but no links
	
	local ozOverlayWithEditableflag = {
		_id = assetId2,
		_serverProvidedMetadata = {
			editable = true
		}
	}
	
	rxTest:waitFor( wfCatalog:docStore():applyOverlay( ozOverlayWithEditableflag ) )
	
	rxTest:expectSingleValue( createCanDeleteObservable( assetId2 ), true )
	
	-- check if asset is in space without local binary
	
	local assetId3 = KSIdGenerator.uuidInLowercaseHex()
	local assetDoc3 = {
		_id = assetId3,
		type = 'asset',
		subtype = 'image',
		_spaceId = spaceId,
		captureDate = KSDate.timeInIso8601Format(),
		develop = {
			croppedHeight = 1000,
			croppedWidth = 1000,
			userOrientation = 1,
		},
	}
	
	rxTest:expectSingleValue( wfCatalog:docStore():setDocValue( assetDoc3 ), ':ignore:' )
	
	rxTest:expectSingleValue( createCanDeleteObservable( assetId3 ), false )
	
	-- check if asset has oz links but no editable flag
	
	local ozOverlayWithLinks = {
		_id = assetId3,
		_serverProvidedMetadata = {
			links = {
				[ '/rels/master' ] = { href = '/href/bogus/testing' },
				[ '/rels/proxy_type/2560' ] = { href = '/href/bogus/proxy' },
				[ '/rels/xmp' ] = { href = '/href/bogus/xmp' }
			}
		}
	}
	
	rxTest:waitFor( wfCatalog:docStore():applyOverlay( ozOverlayWithLinks ) )
	
	rxTest:expectSingleValue( createCanDeleteObservable( assetId3 ), false )
	
	-- check if asset has oz links and editable flag
	
	local ozOverlayWithEditableflagAndLinks = {
		_id = assetId3,
		_serverProvidedMetadata = {
			editable = true,
			links = {
				[ '/rels/master' ] = { href = '/href/bogus/testing' },
				[ '/rels/proxy_type/2560' ] = { href = '/href/bogus/proxy' },
				[ '/rels/xmp' ] = { href = '/href/bogus/xmp' }
			}
		}
	}
	
	rxTest:waitFor( wfCatalog:docStore():applyOverlay( ozOverlayWithEditableflagAndLinks ) )
	
	rxTest:expectSingleValue( createCanDeleteObservable( assetId3 ), true )
	
end

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

function WFCatSharedWithYouUtilsTest.rxTestAssetCanBeDeleted( rxTest )

	rxTest:setTimeLimit( 10 )
	
	local wfCatalog = createFakeWFCatalog( rxTest )
	
	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	local secondsInADay = 86401 -- duh, but don't worry about edge cases
	local timeNow = KSDate.timeInIso8601Format()
	local timeYesterday = KSDate.shiftIso8601DateTime( timeNow, -secondsInADay )
	local timeTwoDaysAgo = KSDate.shiftIso8601DateTime( timeNow, -2 * secondsInADay )
	
	local function createCanDeleteObservable()
		return wfCatalog:docStore()
			:docValue( assetId )
			:map( WFCatSharedWithYouUtils.canDeleteAsset )
	end
	
	-- Insert an asset into the doc store.
	local assetDoc = WFCatAssetTestUtils.createAssetDocument( rxTest, wfCatalog, assetId )
	KSTableUtils_setNested( assetDoc, {
		_serverProvidedMetadata = {
			created = KSDate.timeInIso8601Format(),
		},
	} )
	
	
	rxTest:expectSingleValue( wfCatalog:docStore():setDocValue( assetDoc ), ':ignore:' )
	
	-- This is an asset added by the current user just now, so it can be deleted
	rxTest:expectSingleValue( createCanDeleteObservable(), true )
	
	-- Make this asset added by a different user
	rxTest:expectSingleValue( wfCatalog:docStore():applyOverlay( {
		_id = assetId,
		_spaceId = 'dummy_space_id',
		_serverProvidedMetadata = {
			importedByUser = {
				id = 'some_other_user',
			},
		},
	} ), ':ignore:' )
	
	rxTest:expectSingleValue( createCanDeleteObservable(), false )

	-- Make this asset added by this user, but yesterday
	rxTest:expectSingleValue( wfCatalog:docStore():applyOverlay( {
		_id = assetId,
		_serverProvidedMetadata = {
			importedByUser = { _delete = true },
			created = timeYesterday,
		},
	} ), ':ignore:' )
	
	rxTest:expectSingleValue( createCanDeleteObservable(), true )

	-- Make this asset added by this user, but two days ago
	
	rxTest:expectSingleValue( wfCatalog:docStore():applyOverlay( {
		_id = assetId,
		_serverProvidedMetadata = {
			created = timeTwoDaysAgo,
		},
	} ), ':ignore:' )
	
	rxTest:expectSingleValue( createCanDeleteObservable(), false )

end

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

function WFCatSharedWithYouUtilsTest.rxTestCanDeleteAssetIds( rxTest )

	rxTest:setTimeLimit( 10 )
	
	local wfCatalog = createFakeWFCatalog( rxTest )
	
	local secondsInADay = 86401 -- duh, but don't worry about edge cases
	local timeNow = KSDate.timeInIso8601Format()
	local fiveDaysAgo = KSDate.shiftIso8601DateTime( timeNow, -5 * secondsInADay )
	
	-- Insert some assets into the doc store.
	
	local assetDoc = WFCatAssetTestUtils.createAssetDocument( rxTest, wfCatalog, KSIdGenerator.uuidInLowercaseHex() )
	assetDoc._spaceId = 'dummy_space_id'
	
	KSTableUtils_setNested( assetDoc, KSDate.timeInIso8601Format(), 
			'_serverProvidedMetadata', 'created' )

	rxTest:expectSingleValue( wfCatalog:docStore():setDocValue( assetDoc ), ':ignore:' )
	
	local assetDoc2 = WFCatAssetTestUtils.createAssetDocument( rxTest, wfCatalog, KSIdGenerator.uuidInLowercaseHex() )
	assetDoc2._spaceId = 'dummy_space_id'
	
	KSTableUtils_setNested( assetDoc2, KSDate.timeInIso8601Format(), 
			'_serverProvidedMetadata', 'created' )
	
	rxTest:expectSingleValue( wfCatalog:docStore():setDocValue( assetDoc2 ), ':ignore:' )
	
	local assetDoc3 = WFCatAssetTestUtils.createAssetDocument( rxTest, wfCatalog, KSIdGenerator.uuidInLowercaseHex() )
	assetDoc3._spaceId = 'dummy_space_id'
	
	KSTableUtils_setNested( assetDoc3, fiveDaysAgo, 
			'_serverProvidedMetadata', 'created' )
	
	rxTest:expectSingleValue( wfCatalog:docStore():setDocValue( assetDoc3 ), ':ignore:' )
	
	-- This is an asset added by the current user just now, so it can be deleted
	
	rxTest:expectSingleValue( 
			WFCatSharedWithYouUtils.canDeleteAssetIds( wfCatalog, 
				{
					assetDoc._id,
					assetDoc2._id,
					assetDoc3._id
				} ),
				{
					assetDoc._id,
					assetDoc2._id
				} )

end

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

function WFCatSharedWithYouUtilsTest.rxTestSpaceNeededToContributeAssets( rxTest )

	rxTest:setTimeLimit( 10 )
	
	local wfCatalog = createFakeWFCatalog( rxTest )
	
	-- Insert some assets into the doc store.
	
	local assetDoc1 = WFCatAssetTestUtils.createAssetDocument( rxTest, wfCatalog, KSIdGenerator.uuidInLowercaseHex() )
	KSTableUtils_setNested( assetDoc1, 100,
			'importSource', 'fileSize' )

	local assetDoc2 = WFCatAssetTestUtils.createAssetDocument( rxTest, wfCatalog, KSIdGenerator.uuidInLowercaseHex() )
	KSTableUtils_setNested( assetDoc2, 200,
			'importSource', 'fileSize' )
	
	local assetDoc3 = WFCatAssetTestUtils.createAssetDocument( rxTest, wfCatalog, KSIdGenerator.uuidInLowercaseHex() )
	KSTableUtils_setNested( assetDoc3, 300,
			'importSource', 'fileSize' )
	
	rxTest:expectSingleValue( wfCatalog:docStore():bulkSetDocValue( { assetDoc1, assetDoc2, assetDoc3 } ), ':ignore:' )
	
	rxTest:expectSingleValue( 
			WFCatSharedWithYouUtils.spaceNeededToContributeAssets( wfCatalog, 
				{
					assetDoc1._id,
					assetDoc2._id,
					assetDoc3._id
				} ), 600 )

end

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

return WFRxTestCase.wrapSuite( 'WFCatSharedWithYouUtilsTest', WFCatSharedWithYouUtilsTest )
