--[[----------------------------------------------------------------------------
ADOBE CONFIDENTIAL
------------------
Copyright 2017 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.
----------------------------------------------------------------------------]]--

local WFRxTestCase = require 'WFRxTestCase'
local LrmCatCollaboration = require 'LrmCatCollaboration'
local WFPlatformInfo = require 'WFPlatformInfo'
local WFCatCollaborationActivityTestUtils = require 'WFCatCollaborationActivityTestUtils'
local WFCatMockCatalog = require 'WFCatMockCatalog'
local KSIdGenerator = require 'KSIdGenerator'

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

local LrmCatCollaborationTest = {}

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

local catalogOptions = {
	indexDefinitions = 'LrmCatalogIndexDefinitions.lua'
}

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

function LrmCatCollaborationTest.rxTestHasCommentsInAlbum( rxTest )

	-- Test setup with a new album, space, asset, and comment

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )

	local docStore = wfCatalog:docStore()

	local albumInfo, assetInfo = WFCatCollaborationActivityTestUtils.createSharedAlbumWithAsset( rxTest, wfCatalog, { useMockOz = false } )

	local comments = {
		WFCatCollaborationActivityTestUtils.createComment( albumInfo.spaceId, assetInfo.globalId, wfCatalog:ozUserId(), "comment1" ),
	}

	local persistedComments = rxTest:getFirstValue( docStore:bulkSetDocValue( comments ) )

	-- Observe hasCommentsInAblum because the structure does not have a termination condition which would
	-- allow getFirstValue etc, to work
	local observer = rxTest:observe( LrmCatCollaboration.hasCommentsInAlbum( wfCatalog, albumInfo.globalId ) )

	observer:expectDataWithinTime( 1, persistedComments[1].id )

end

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

function LrmCatCollaborationTest.rxTestHasSpaceFavoritesInAlbum( rxTest )

	rxTest:setTimeLimit(5)
	-- Test setup with a new album, space, asset, and favorite
	
	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )

	local docStore = wfCatalog:docStore()

	local albumInfo, assetInfo = WFCatCollaborationActivityTestUtils.createSharedAlbumWithAsset( rxTest, wfCatalog, { useMockOz = false } )

	-- Simulate already added favorites
	local currUserId = wfCatalog:ozUserId()
	local favorites = {
		WFCatCollaborationActivityTestUtils.createFavorite( albumInfo.spaceId, assetInfo.globalId, currUserId ),
	}

	local persistedFavorites = rxTest:getFirstValue( docStore:bulkSetDocValue( favorites ) )

	-- Observe hasCommentsInAblum because the structure does not have a termination condition which would
	-- allow getFirstValue etc, to work
	local observer = rxTest:observe( LrmCatCollaboration.hasSpaceFavoritesInAlbum( wfCatalog, albumInfo.globalId ) )

	observer:expectDataWithinTime( 1, persistedFavorites[1].id )

end

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

function LrmCatCollaborationTest.rxTestAddComment( rxTest )

	rxTest:setTimeLimit(10)
	
	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )

	local albumInfo, assetInfo = WFCatCollaborationActivityTestUtils.createSharedAlbumWithAsset( rxTest, wfCatalog, { useMockOz = false } )

	-- test comment error
	rxTest:expectSpecificError("LrmCatCollaboration:addComment: The comment body must be a non-empty string",
		function() LrmCatCollaboration.addComment( wfCatalog, albumInfo.globalId, assetInfo.globalId, {} ) end)

	local observer = rxTest:observe( LrmCatCollaboration.hasCommentsInAlbum(wfCatalog, albumInfo.globalId) )

	observer:expectDataWithinTime(1, nil)
	
	local comments = { WFCatCollaborationActivityTestUtils.createComment( albumInfo.spaceId, assetInfo.globalId, wfCatalog:ozUserId(), "Hi" ) }

	local commentId = rxTest:waitFor( LrmCatCollaboration.addComment( wfCatalog, albumInfo.globalId, assetInfo.globalId, comments ))

	observer:expectDataWithinTime(1, commentId)

end

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

function LrmCatCollaborationTest.rxTestToggleMySpaceFavorite( rxTest )

	rxTest:setTimeLimit( 10 )
	
	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )
	
	local albumInfo, assetInfo = WFCatCollaborationActivityTestUtils.createSharedAlbumWithAsset( rxTest, wfCatalog, { useMockOz = false } )
	
	local favoriteObserver = rxTest:observe( LrmCatCollaboration.getSpaceFavoritesOnAlbumAsset( wfCatalog, albumInfo.globalId, assetInfo.globalId )
		:map(function(favorites)
		
				if favorites and type(favorites) == 'table' and #favorites > 0 then
					return favorites[1].assetId
				end

				return "No Favorites"
				
			end))


	favoriteObserver:expectDataWithinTime( 1, "No Favorites" )

	-- toggle asset to be a favorite
	rxTest:waitFor( LrmCatCollaboration.toggleMySpaceFavorite( wfCatalog, assetInfo.globalId, albumInfo.globalId ) )

	-- expect that the asset Id will be returned
	favoriteObserver:expectDataWithinTime( 1, assetInfo.globalId )
end

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

function LrmCatCollaborationTest.rxTestShareAssetOrAlbum( rxTest )

	--[SPAM @sewillia 2021-08-26] Album Test. There is not a wrapper function of the asset case, so I am not sure it is used

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )
	
	local albumInfo, _ = WFCatCollaborationActivityTestUtils.createAlbumWithAsset( rxTest, wfCatalog )
	
	rxTest:expectSingleValue( LrmCatCollaboration.isAlbumShared( wfCatalog, albumInfo.globalId ), false )

	rxTest:waitFor( LrmCatCollaboration.shareAssetOrAlbum( wfCatalog, 'album', albumInfo.globalId, nil ) )
	
	rxTest:expectSingleValue( LrmCatCollaboration.isAlbumShared( wfCatalog, albumInfo.globalId ), true)

end

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

function LrmCatCollaborationTest.rxTestUnshareAssetOrAlbum( rxTest )

	--[SPAM @sewillia 2021-08-26] Album Test. There is not a wrapper function of the asset case, so I am not sure it is used
	
	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )
	
	local albumInfo, _ = WFCatCollaborationActivityTestUtils.createAlbumWithAsset( rxTest, wfCatalog )
	
	rxTest:waitFor( LrmCatCollaboration.shareAssetOrAlbum( wfCatalog, 'album', albumInfo.globalId, nil ) )
	
	rxTest:expectSingleValue( LrmCatCollaboration.isAlbumShared( wfCatalog, albumInfo.globalId ), true )

	rxTest:waitFor( LrmCatCollaboration.unshareAssetOrAlbum( wfCatalog, 'album', albumInfo.globalId ) )
	
	rxTest:expectSingleValue( LrmCatCollaboration.isAlbumShared( wfCatalog, albumInfo.globalId ), false )

end

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

function LrmCatCollaborationTest.rxTestOngoingSharedAssetOrAlbumUrl( rxTest )
	-- FIXME: Converge API to use WFCatCollaboration WF-1737
end

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

function LrmCatCollaborationTest.rxTestSharedAssetOrAlbumUrl( rxTest )
	-- FIXME: Converge API to use WFCatCollaboration WF-1737
end

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

function LrmCatCollaborationTest.rxTestResolveAlbumFromSpace( rxTest )

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )
	
	local albumInfo, _ = WFCatCollaborationActivityTestUtils.createSharedAlbumWithAsset( rxTest, wfCatalog, { useMockOz = false } )
	
	rxTest:expectSingleValue( LrmCatCollaboration.resolveAlbumFromSpace( wfCatalog, albumInfo.spaceId ), albumInfo.globalId )
	
end

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

function LrmCatCollaborationTest.rxTestShareAlbum( rxTest )

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )
	
	local albumInfo, _ = WFCatCollaborationActivityTestUtils.createAlbumWithAsset( rxTest, wfCatalog )
	
	rxTest:expectSingleValue( LrmCatCollaboration.isAlbumShared( wfCatalog, albumInfo.globalId ), false )

	rxTest:waitFor( LrmCatCollaboration.shareAlbum( wfCatalog, albumInfo.globalId, nil ) )
		
	rxTest:expectSingleValue( LrmCatCollaboration.isAlbumShared( wfCatalog, albumInfo.globalId ), true )
		
end

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

function LrmCatCollaborationTest.rxTestUnshareAlbum( rxTest )

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )
	
	local albumInfo, _ = WFCatCollaborationActivityTestUtils.createAlbumWithAsset( rxTest, wfCatalog )
	
	rxTest:waitFor( LrmCatCollaboration.shareAlbum( wfCatalog, albumInfo.globalId, nil ) )
	
	rxTest:expectSingleValue( LrmCatCollaboration.isAlbumShared( wfCatalog, albumInfo.globalId ), true )

	rxTest:waitFor( LrmCatCollaboration.unshareAlbum( wfCatalog, albumInfo.globalId ) )
	
	rxTest:expectSingleValue( LrmCatCollaboration.isAlbumShared( wfCatalog, albumInfo.globalId ), false )

end

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

function LrmCatCollaborationTest.rxTestGetComments( rxTest )

	rxTest:setTimeLimit(10)
	-- Test setup with a new album, space, asset, and comment

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )
	
	local docStore = wfCatalog:docStore()

	local albumInfo, assetInfo = WFCatCollaborationActivityTestUtils.createSharedAlbumWithAsset( rxTest, wfCatalog, { useMockOz = false } )

	-- Simulate already added comments

	local comments = {
		WFCatCollaborationActivityTestUtils.createComment( albumInfo.spaceId, assetInfo.globalId, wfCatalog:ozUserId(), "comment1" ),
	}

	local persistedComments = rxTest:getFirstValue( docStore:bulkSetDocValue( comments ) )

	local observer = rxTest:observe(
		LrmCatCollaboration.getComments( wfCatalog )
		:map(function(v)
			if v and type(v) == 'table' and #v > 0 then
				-- This is a rigid assumption. It would be better to write a test of
				-- inclusion in a table rather than strictly looking at an index
				return v[1].id
			else
				return v
			end
		end)

	)

	observer:expectDataWithinTime( 1, persistedComments[1].id )

end

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

function LrmCatCollaborationTest.rxTestGetCommentsForAlbum( rxTest )

	rxTest:setTimeLimit(10)
	
	-- Test setup with a new album, space, asset, and comment

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )
	
	local docStore = wfCatalog:docStore()

	local albumInfo, assetInfo = WFCatCollaborationActivityTestUtils.createSharedAlbumWithAsset( rxTest, wfCatalog, { useMockOz = false } )

	-- Simulate already added comments

	local comments = {
		WFCatCollaborationActivityTestUtils.createComment( albumInfo.spaceId, assetInfo.globalId, wfCatalog:ozUserId(), "comment1" ),
	}

	local persistedComments = rxTest:getFirstValue( docStore:bulkSetDocValue( comments ) )

	local observer = rxTest:observe(
		LrmCatCollaboration.getCommentsForAlbum( wfCatalog, albumInfo.globalId )
		:map(function(v)
			if v and type(v) == 'table' and #v > 0 then
				-- This is a rigid assumption. It would be better to write a test of
				-- inclusion in a table rather than strictly looking at an index
				return v[1].id
			else
				return v
			end
		end)

	)

	observer:expectDataWithinTime( 1, persistedComments[1].id )
end

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

function LrmCatCollaborationTest.rxTestGetCommentsOnAlbumAsset( rxTest )

	rxTest:setTimeLimit(10)
	-- Test setup with a new album, space, asset, and comment

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )
	
	local docStore = wfCatalog:docStore()

	local albumInfo, assetInfo = WFCatCollaborationActivityTestUtils.createSharedAlbumWithAsset( rxTest, wfCatalog, { useMockOz = false } )

	-- Simulate already added comments

	local comments = {
		WFCatCollaborationActivityTestUtils.createComment( albumInfo.spaceId, assetInfo.globalId, wfCatalog:ozUserId(), "comment1" ),
	}

	local persistedComments = rxTest:getFirstValue( docStore:bulkSetDocValue( comments ) )

	local observer = rxTest:observe(
		LrmCatCollaboration.getCommentsOnAlbumAsset( wfCatalog, albumInfo.globalId, assetInfo.globalId )
		:map(function(v)
			if v and type(v) == 'table' and #v > 0 then
				-- This is a rigid assumption. It would be better to write a test of
				-- inclusion in a table rather than strictly looking at an index
				return v[1].id
			else
				return v
			end
		end)

	)

	observer:expectDataWithinTime( 1, persistedComments[1].id )
end

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

function LrmCatCollaborationTest.rxTestGetSpaceFavoritesOnAlbum( rxTest )

	rxTest:setTimeLimit(10)
	-- Test setup with a new album, space, asset, and comment

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )
	
	local albumInfo, assetInfo = WFCatCollaborationActivityTestUtils.createSharedAlbumWithAsset( rxTest, wfCatalog, { useMockOz = false } )
	
	-- toggle asset to be a favorite
	rxTest:waitFor( LrmCatCollaboration.toggleMySpaceFavorite( wfCatalog, assetInfo.globalId, albumInfo.globalId ) )

	local observer = rxTest:observe(
		LrmCatCollaboration.getSpaceFavoritesOnAlbum( wfCatalog, albumInfo.globalId )
		:map(function(v)
			if v and type(v) == 'table' and #v > 0 then
				-- This is a rigid assumption. It would be better to write a test of
				-- inclusion in a table rather than strictly looking at an index
				return v[1].assetId
			else
				return v
			end
		end)

	)

	observer:expectDataWithinTime( 1, assetInfo.globalId )
end

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

function LrmCatCollaborationTest.rxTestGetSpaceFavorites( rxTest )

	rxTest:setTimeLimit(10)
	-- Test setup with a new album, space, asset, and comment

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )
	
	local albumInfo, assetInfo = WFCatCollaborationActivityTestUtils.createSharedAlbumWithAsset( rxTest, wfCatalog, { useMockOz = false } )
	
	-- toggle asset to be a favorite
	rxTest:waitFor( LrmCatCollaboration.toggleMySpaceFavorite( wfCatalog, assetInfo.globalId, albumInfo.globalId ) )

	local observer = rxTest:observe(
		LrmCatCollaboration.getSpaceFavorites( wfCatalog, albumInfo.globalId, assetInfo.globalId )
		:map(function(v)
			if v and type(v) == 'table' and #v > 0 then
				-- This is a rigid assumption. It would be better to write a test of
				-- inclusion in a table rather than strictly looking at an index
				return v[1].assetId
			else
				return v
			end
		end)

	)

	observer:expectDataWithinTime( 1, assetInfo.globalId )
end

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

function LrmCatCollaborationTest.rxTestGetSpaceFavoritesOnAlbumAsset( rxTest )

	rxTest:setTimeLimit(10)
	-- Test setup with a new album, space, asset, and comment

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )
	
	local albumInfo, assetInfo = WFCatCollaborationActivityTestUtils.createSharedAlbumWithAsset( rxTest, wfCatalog, { useMockOz = false } )
	
	-- toggle asset to be a favorite
	rxTest:waitFor( LrmCatCollaboration.toggleMySpaceFavorite( wfCatalog, assetInfo.globalId, albumInfo.globalId ) )

	local observer = rxTest:observe(
		LrmCatCollaboration.getSpaceFavoritesOnAlbumAsset( wfCatalog, albumInfo.globalId, assetInfo.globalId )
		:map(function(v)
			if v and type(v) == 'table' and #v > 0 then
				-- This is a rigid assumption. It would be better to write a test of
				-- inclusion in a table rather than strictly looking at an index
				return v[1].assetId
			else
				return v
			end
		end)

	)

	observer:expectDataWithinTime( 1, assetInfo.globalId )
end

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

function LrmCatCollaborationTest.rxTestIsMySpaceFavorite( rxTest )
	rxTest:setTimeLimit(5)

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )
	
	local albumInfo, assetInfo = WFCatCollaborationActivityTestUtils.createSharedAlbumWithAsset( rxTest, wfCatalog, { useMockOz = false } )

	local observer = rxTest:observe( LrmCatCollaboration.isMySpaceFavorite( wfCatalog, assetInfo.globalId, albumInfo.globalId, wfCatalog:ozUserId() ) )

	observer:expectDataWithinTime( 1, false )	

	-- toggle space to be a favorite
	rxTest:waitFor( LrmCatCollaboration.toggleMySpaceFavorite( wfCatalog, assetInfo.globalId, albumInfo.globalId ) )

	observer:expectDataWithinTime( 1, true )
	
	-- toggle space to un-favorite
	rxTest:waitFor( LrmCatCollaboration.toggleMySpaceFavorite( wfCatalog, assetInfo.globalId, albumInfo.globalId ) )

	observer:expectDataWithinTime( 1, false )
	
end

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

function LrmCatCollaborationTest.rxTestIsMySpaceFavoriteWithSharedWithYouUser( rxTest )
	rxTest:setTimeLimit(5)

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, catalogOptions )
	local docStore = wfCatalog:docStore()
	
	-- Create a shared album with asset
	local albumInfo, assetInfo = WFCatCollaborationActivityTestUtils.createSharedAlbumWithAsset( rxTest, wfCatalog, { useMockOz = false } )

	-- Create space document with this_space_user
	local spaceUserId = KSIdGenerator.uuidInLowercaseHex()
	local feedbackUserId = KSIdGenerator.uuidInLowercaseHex()

	local spaceDoc = {
		_id = albumInfo.spaceId,
		type = 'space',
		subtype = 'shared',
		_serverProvidedMetadata = {
			this_space_user = {
				id = spaceUserId,
				user = {
					id = feedbackUserId
				}
			}
		}
	}

	rxTest:waitFor( docStore:applyOverlay( spaceDoc ) )

	-- Create observer to check favorite status
	local observer = rxTest:observe( LrmCatCollaboration.isMySpaceFavorite( wfCatalog, assetInfo.globalId, albumInfo.globalId ) )

	observer:expectDataWithinTime( 1, false )

	-- toggle space to be a favorite
	rxTest:waitFor( LrmCatCollaboration.toggleMySpaceFavorite( wfCatalog, assetInfo.globalId, albumInfo.globalId ) )

	observer:expectDataWithinTime( 1, true )

	-- toggle space to un-favorite
	rxTest:waitFor( LrmCatCollaboration.toggleMySpaceFavorite( wfCatalog, assetInfo.globalId, albumInfo.globalId ) )

	observer:expectDataWithinTime( 1, false )
end

if WFPlatformInfo.isDesktop then
	return {}
else
	return WFRxTestCase.wrapSuite( 'LrmCatCollaborationTest', LrmCatCollaborationTest )
end

