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

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.

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

	-- WF.core.rxlua
local WFRxTestCase = require 'WFRxTestCase'

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

	-- WF.oz_client.managed_catalog
local WFCatAlbumTestUtils = require 'WFCatAlbumTestUtils'
local WFCatAssetTestUtils = require 'WFCatAssetTestUtils'
local WFCatMockCatalog = require 'WFCatMockCatalog'

	-- WF.oz_client.managed_catalog.search_sort
local WFCatSortByAssetId = require 'WFCatSortByAssetId'
local WFCatSortByCustomOrder = require 'WFCatSortByCustomOrder'
local WFCatSortByFileName = require 'WFCatSortByFileName'
local WFCatSortByImportTime = require 'WFCatSortByImportTime'
local WFCatSortByModifiedTime = require 'WFCatSortByModifiedTime'
local WFCatSortByRating = require 'WFCatSortByRating'
local WFCatSortByRecentlyEdited = require 'WFCatSortByRecentlyEdited'

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

local WFCatSortByQueriesTest = {}

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

local function createAssetDocument( rxTest, wfCatalog, optArgs )

	optArgs = optArgs or {}

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	local assetDocValue = WFCatAssetTestUtils.createAssetDocument( rxTest, wfCatalog, assetId, optArgs )

	if optArgs.fileName then
		KSTableUtils.setNested( assetDocValue, optArgs.fileName, 'importSource', 'fileName' )
	end
	
	if optArgs.importTime then
		KSTableUtils.setNested( assetDocValue, optArgs.importTime, 'importSource', 'importTimestamp' )
	end
	
	if optArgs.modifiedTime then
		KSTableUtils.setNested( assetDocValue, optArgs.modifiedTime, 'userUpdated' )
	end
	
	if optArgs.rating then
		KSTableUtils.setNested( assetDocValue, optArgs.rating, 'ratings', KSIdGenerator.uuidInLowercaseHex(), 'rating' )
	end
	
	if optArgs.editedTime then
		KSTableUtils.setNested( assetDocValue, optArgs.editedTime, 'develop', 'userUpdated' )
	end

	rxTest:waitFor( wfCatalog:docStore():setDocValue( assetDocValue ) )
	
	local assetLocalId = rxTest:getFirstValue( wfCatalog:docStore():docValue( assetId ):pluck( "_localId" ) )
	
	return assetLocalId, assetId

end

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

function WFCatSortByQueriesTest.rxTestSortByAssetId( rxTest )
	
	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest )
	
	local assetLocalId1 = createAssetDocument( rxTest, wfCatalog )
	
	local assetLocalId2 = createAssetDocument( rxTest, wfCatalog )
	
	local assetLocalId3 = createAssetDocument( rxTest, wfCatalog )
	
	local assetLocalIds = { assetLocalId2, assetLocalId1, assetLocalId3 }
	
	local expectedData = { 
		{
			assetLocalId3,
			0,
		},
		{
			assetLocalId2,
			0,
		},
		{
			assetLocalId1,
			0,
		}
	}

	rxTest:expectSingleValue(
			WFCatSortByAssetId.executeSort( wfCatalog, assetLocalIds ),
			expectedData )

end

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

function WFCatSortByQueriesTest.rxTestSortByCustomOrder( rxTest )
	
	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest )
	
	local assetLocalId1, assetId1 = createAssetDocument( rxTest, wfCatalog )
	
	local assetLocalId2, assetId2 = createAssetDocument( rxTest, wfCatalog )
	
	local assetLocalId3, assetId3 = createAssetDocument( rxTest, wfCatalog )
	
	local albumDoc = WFCatAlbumTestUtils.createEmptyCollection( rxTest )
	
	local albumAssetDoc1 = WFCatAlbumTestUtils.createAlbumAsset( rxTest, albumDoc._id, assetId1 )
	local albumAssetDoc2 = WFCatAlbumTestUtils.createAlbumAsset( rxTest, albumDoc._id, assetId2 )
	local albumAssetDoc3 = WFCatAlbumTestUtils.createAlbumAsset( rxTest, albumDoc._id, assetId3 )
	
	rxTest:waitFor( wfCatalog:docStore():bulkSetDocValue( { albumDoc, albumAssetDoc1, albumAssetDoc2, albumAssetDoc3 } ) )
	
	local assetLocalIds = { assetLocalId2, assetLocalId1, assetLocalId3 }
	
	local expectedData = { 
		{
			assetLocalId3,
			assetId3,
		},
		{
			assetLocalId2,
			assetId2,
		},
		{
			assetLocalId1,
			assetId1,
		}
	}
	
	local order = 'DESC'
	
	local observer = rxTest:observe( 
			WFCatSortByCustomOrder.executeSort( wfCatalog, assetLocalIds, order, {} ) ) 

	observer:expectDataWithinTime( 2, expectedData )
	
end

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

function WFCatSortByQueriesTest.rxTestSortByFileName( rxTest )
	
	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest )
	
	local optArgs = {
		fileName = 'foo'
	}
	
	local assetLocalId1 = createAssetDocument( rxTest, wfCatalog, optArgs )
	
	optArgs = {
		fileName = 'bar'
	}
	
	local assetLocalId2 = createAssetDocument( rxTest, wfCatalog, optArgs )
	
	optArgs = {
		fileName = 'baz'
	}
	
	local assetLocalId3 = createAssetDocument( rxTest, wfCatalog, optArgs )
	
	local assetLocalIds = { assetLocalId2, assetLocalId1, assetLocalId3 }
	
	local expectedData = { 
		{
			assetLocalId1,
			'foo',
		},
		{
			assetLocalId3,
			'baz',
		},
		{
			assetLocalId2,
			'bar',
		}
	}
	
	local observer = rxTest:observe( 
			WFCatSortByFileName.executeSort( wfCatalog, assetLocalIds ) ) 

	observer:expectDataWithinTime( 2, expectedData )
	
end

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

function WFCatSortByQueriesTest.rxTestSortByImportTime( rxTest )
	
	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest )
	
	local optArgs = {
		importTime = KSDate.timeInIso8601Format()
	}
	
	local assetLocalId1 = createAssetDocument( rxTest, wfCatalog, optArgs )
	
	local sevenDaysAgo = KSDate.shiftIso8601DateTime( KSDate.timeInIso8601Format(), - ( 7 * 24 * 60 * 60 ) )
	
	optArgs = {
		importTime = sevenDaysAgo
	}
	
	local assetLocalId2 = createAssetDocument( rxTest, wfCatalog, optArgs )
	
	local twoDaysAgo = KSDate.shiftIso8601DateTime( KSDate.timeInIso8601Format(), - ( 2 * 24 * 60 * 60 ) )
	
	optArgs = {
		importTime = twoDaysAgo
	}
	
	local assetLocalId3 = createAssetDocument( rxTest, wfCatalog, optArgs )
	
	local assetLocalIds = { assetLocalId2, assetLocalId1, assetLocalId3 }
	
	local expectedData = { 
		{
			assetLocalId1,
			'date',
		},
		{
			assetLocalId3,
			'date',
		},
		{
			assetLocalId2,
			'date',
		}
	}
	
	local observer = rxTest:observe( 
			WFCatSortByImportTime.executeSort( wfCatalog, assetLocalIds )
				:map( function( rows )
				
					for _, row in ipairs( rows ) do
				
						row[ 2 ] = 'date' -- Map out hard to compare values.
				
					end
				
					return rows
				
				end ) ) 

	observer:expectDataWithinTime( 2, expectedData )
	
end

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

function WFCatSortByQueriesTest.rxTestSortByModifiedTime( rxTest )

	rxTest:setTimeLimit( 10 )
	
	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest )
	
	local optArgs = {
		modifiedTime = KSDate.timeInIso8601Format()
	}
	
	local assetLocalId1 = createAssetDocument( rxTest, wfCatalog, optArgs )
	
	local sevenDaysAgo = KSDate.shiftIso8601DateTime( KSDate.timeInIso8601Format(), - ( 7 * 24 * 60 * 60 ) )
	
	optArgs = {
		modifiedTime = sevenDaysAgo
	}
	
	local assetLocalId2 = createAssetDocument( rxTest, wfCatalog, optArgs )
	
	local twoDaysAgo = KSDate.shiftIso8601DateTime( KSDate.timeInIso8601Format(), - ( 2 * 24 * 60 * 60 ) )
	
	optArgs = {
		modifiedTime = twoDaysAgo
	}
	
	local assetLocalId3 = createAssetDocument( rxTest, wfCatalog, optArgs )
	
	local assetLocalIds = { assetLocalId2, assetLocalId1, assetLocalId3 }
	
	local expectedData = { 
		{
			assetLocalId1,
			'date',
		},
		{
			assetLocalId3,
			'date',
		},
		{
			assetLocalId2,
			'date',
		}
	}
	
	local observer = rxTest:observe( 
			WFCatSortByModifiedTime.executeSort( wfCatalog, assetLocalIds )
				:map( function( rows )
				
					for _, row in ipairs( rows ) do
				
						row[ 2 ] = 'date' -- Map out hard to compare values.
				
					end
				
					return rows
				
				end ) ) 

	observer:expectDataWithinTime( 2, expectedData )
	
end

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

function WFCatSortByQueriesTest.rxTestSortByRating( rxTest )
	
	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest )
	
	local optArgs = {
		rating = 1
	}
	
	local assetLocalId1 = createAssetDocument( rxTest, wfCatalog, optArgs )
	
	optArgs = {
		rating = 5
	}
	
	local assetLocalId2 = createAssetDocument( rxTest, wfCatalog, optArgs )
	
	optArgs = {
		rating = 2
	}
	
	local assetLocalId3 = createAssetDocument( rxTest, wfCatalog, optArgs )
	
	local assetLocalIds = { assetLocalId2, assetLocalId1, assetLocalId3 }
	
	local expectedData = { 
		{
			assetLocalId2,
			5,
		},
		{
			assetLocalId3,
			2,
		},
		{
			assetLocalId1,
			1,
		}
	}
	
	local observer = rxTest:observe( 
			WFCatSortByRating.executeSort( wfCatalog, assetLocalIds ) ) 

	observer:expectDataWithinTime( 2, expectedData )
	
end

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

function WFCatSortByQueriesTest.rxTestSortByRecentlyEdited( rxTest )
	
	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest )
	
	local optArgs = {
		editedTime = KSDate.timeInIso8601Format()
	}
	
	local assetLocalId1 = createAssetDocument( rxTest, wfCatalog, optArgs )
	
	local sevenDaysAgo = KSDate.shiftIso8601DateTime( KSDate.timeInIso8601Format(), - ( 7 * 24 * 60 * 60 ) )
	
	optArgs = {
		editedTime = sevenDaysAgo
	}
	
	local assetLocalId2 = createAssetDocument( rxTest, wfCatalog, optArgs )
	
	local twoDaysAgo = KSDate.shiftIso8601DateTime( KSDate.timeInIso8601Format(), - ( 2 * 24 * 60 * 60 ) )
	
	optArgs = {
		editedTime = twoDaysAgo
	}
	
	local assetLocalId3 = createAssetDocument( rxTest, wfCatalog, optArgs )
	
	local assetLocalIds = { assetLocalId2, assetLocalId1, assetLocalId3 }
	
	local expectedData = { 
		{
			assetLocalId1,
			'date',
		},
		{
			assetLocalId3,
			'date',
		},
		{
			assetLocalId2,
			'date',
		}
	}
	
	local observer = rxTest:observe( 
			WFCatSortByRecentlyEdited.executeSort( wfCatalog, assetLocalIds )
				:map( function( rows )
				
					for _, row in ipairs( rows ) do
				
						row[ 2 ] = 'date' -- Map out hard to compare values.
				
					end
				
					return rows
				
				end ) ) 

	observer:expectDataWithinTime( 2, expectedData )
	
end

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

return WFRxTestCase.wrapSuite( 'WFCatSortByQueriesTest', WFCatSortByQueriesTest )
