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

WFCatAlbumTestUtils.lua

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

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.utils
local KSIdGenerator = require 'KSIdGenerator'

	-- WF.oz_client
local WFCatAssetTestUtils = require 'WFCatAssetTestUtils'

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

--[[
	
	WFCatAlbumTestUtils is used for quickly generating albums in a variety of
	states for testing. 
]]--

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

local WFCatAlbumTestUtils = {}

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

--[[
	@mark Helper Functions
]]--
--------------------------------------------------------------------------------
--[[!
	\brief Creates an album asset.

	\param rxTest (rxTest)
	\param albumId (optional string) optional album Id.
	\param assetId (optional string) optional asset Id.
	\param albumAssetId (optional string) optional album asset Id.
		
	\return (table) The specified album asset document.
--]]

function WFCatAlbumTestUtils.createAlbumAsset( rxTest, albumId, assetId, albumAssetId )

	albumId = albumId or KSIdGenerator.uuidInLowercaseHex()
	albumAssetId = albumAssetId or KSIdGenerator.uuidInLowercaseHex()
	assetId = assetId or KSIdGenerator.uuidInLowercaseHex()
	
	local albumAssetDoc = {
		_id = albumAssetId,
		type = 'album_asset',
		album = {
			id = albumId,
		},
		asset = {
			id = assetId,
		},
	}
	
	return albumAssetDoc
	
end

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

--[[!
	\brief Inserts assets and matching album assets into an album.

	\param rxTest (rxTest)
	\param albumId (string) optional album Id.
	\param assetId (string) optional asset Id.
	\param assetCount (number) number of assets.
	\param optOverrides (table) optional table that influences asset creation
		
	\return (table) The document Ids of the created asset documents.
--]]
function WFCatAlbumTestUtils.insertAlbumAssets( rxTest, wfCatalog, albumId, assetCount, optOverrides )

	return WFCatAssetTestUtils.insertAssets( rxTest, wfCatalog, assetCount, optOverrides )
		:flatMap( function( assetIds )

			local albumAssetOverlays = {}

			for i = 1, assetCount do

				local docValue = WFCatAlbumTestUtils.createAlbumAsset( rxTest, albumId, assetIds[ i ] )

				albumAssetOverlays[ #albumAssetOverlays + 1 ] = docValue

			end

			return wfCatalog:docStore():bulkApplyOverlay( albumAssetOverlays )
				:map( function()
					return assetIds
				end )

		end )
end

--------------------------------------------------------------------------------
--[[!
	\brief Add documents to an collection.

	\param rxTest (rxTest)
	\param albums (table) table of albums to be added.
	\param collection (table) collections where albums will be added.
	\param collectionId (optional string) optional collection Id for parent field.
		
	\return (table) The specified collection with given albums.
--]]

local function addAlbumToCollection( rxTest, albumDocs, collection, collectionId )

	for j, doc in ipairs(albumDocs) do
		if doc.subtype == "collection_set" then
			doc.parent = collectionId or KSIdGenerator.uuidInLowercaseHex()
		end
		table.insert(collection, doc)
	end
	
	return collection
	
end

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

function WFCatAlbumTestUtils.createEmptyCollection( rxTest, docId )
	
	docId = docId or KSIdGenerator.uuidInLowercaseHex()
	
	local document = {
		_id = docId,
		name = 'Test collection',
		type = "album",
		subtype = "collection",
	}
		
	return document
	
end

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

--@mark Album Creation

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

--[[!
	\brief Creates an empty album asset.

	\param rxTest (rxTest)
	\param albumId (optional string) optional document Id.
	\param parent (optional bool) if true a parent field will be added.
	\param parentId (optional string) if given a specific parent Id will be used.
	
	\return (table) The empty album document.
--]]

function WFCatAlbumTestUtils.createEmptyAlbumDoc( rxTest, albumId, parent, parentId )

	albumId = albumId or KSIdGenerator.uuidInLowercaseHex()
	
	local emptyAlbum = {
			_id = albumId,
			name = 'Test album',
			type = "album",
			subtype = "collection_set",
			}
	
	if parent == true then
		emptyAlbum.parent = parentId or KSIdGenerator.uuidInLowercaseHex()
	end
	
	return emptyAlbum
	
end

--------------------------------------------------------------------------------
--[[!
	\brief Creates an album.

	\param rxTest (rxTest)
	\param wfCatalog (WFCatalog)
	\param albumId (optional string) optional document Id.
	\param optOverrides (optional table) Optional document modifiers:
		addDocuments(table): add the given assets to album and generate albumAsset document.
		createImages(integer): the number of images to be created along
						with their album assets.
		parent(bool): add a parent field to the album_set document
		parentId(integer): give the parent a specific ID
		
	\return (table) A table containing the specified album and assets.
--]]

function WFCatAlbumTestUtils.createAlbumDocument( rxTest, wfCatalog, albumId, optOverrides )

	local albumDoc = WFCatAlbumTestUtils.createEmptyAlbumDoc( rxTest, albumId, optOverrides.parent, optOverrides.parentId )
	local documentTable = {albumDoc}
	albumId = albumId or KSIdGenerator.uuidInLowercaseHex()
	optOverrides = optOverrides or {}

	--Add assets if any are given
	if optOverrides.addDocuments then
		for i, document in ipairs(optOverrides.addDocuments) do
			--TODO: See if KSTableUtils.appendArray( album, documents ) works better
			local albumAsset = WFCatAlbumTestUtils.createAlbumAsset( rxTest, albumId, document["_id"], optOverrides.albumAssetIds[i] )
			table.insert( documentTable, document )
			table.insert( documentTable, albumAsset )
		end
	end
	
	--Create the specified number of images and add album assets for 
	if optOverrides.createImages then
		for i=optOverrides.createImages, 1, -1 do
			local image = WFCatAssetTestUtils.createAssetDocument( rxTest, wfCatalog )
			local albumAsset = WFCatAlbumTestUtils.createAlbumAsset( rxTest, albumId, image["_id"] )
			table.insert(documentTable, image)
			table.insert(documentTable, albumAsset)
		end		
	end
	
	return documentTable
	
end

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

--[[
	@mark Collection Creation
]]--
--------------------------------------------------------------------------------
--[[!
	\brief Creates album collections for use in tests.

	\param rxTest (rxTest)
	\param wfCatalog (WFCatalog)
	\param collectionId (Optional String) optional collection Id.
	\param optOverrides (Optional Table) Optional document modifiers:
		addAlbumDocTable ( Table ): Adds a table of documents and adds a subtype of collection_set 
									and a parent id to any album document.
		numberOfAlbumsToCreate (Integer): The number of album documents to add to the table.  
		numberOfImagesToCreateInEachAlbum (Integer): Indicates the number of images with each album
													as it's parent. 

	\return (table) The Album collection.
--]]

function WFCatAlbumTestUtils.createCollectionSet( rxTest, wfCatalog, collectionId, optOverrides)

	collectionId = collectionId or KSIdGenerator.uuidInLowercaseHex()
	optOverrides = optOverrides or {}
	local collectionDoc = WFCatAlbumTestUtils.createEmptyCollection( rxTest, collectionId)
	local documentTable = {collectionDoc}
	
	--Add albums if any are given
	if optOverrides.addAlbums then
		for i, album in ipairs(optOverrides.addAlbums) do
			for j, doc in ipairs(album) do
				if doc.subtype == "collection_set" then
					doc.parent = collectionId
				end
				table.insert(documentTable, doc)
			end
		end
	end
	
	--Create albums with specifications
	if optOverrides.createAlbums then
		local albumOverrides = {
			createImages = optOverrides.createImagesOnAlbums,
			parent = true,
			parentId = collectionId
		}
			
		local numOfDocsToCreate = optOverrides.createAlbums or 1
		for k=numOfDocsToCreate, 1, -1 do
			local createdAlbum = WFCatAlbumTestUtils.createAlbumDocument( rxTest, wfCatalog, nil, albumOverrides )
			documentTable = addAlbumToCollection( rxTest, createdAlbum, documentTable, collectionId )
		end
	end
	
	return documentTable
	
end

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

return WFCatAlbumTestUtils