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

NmbOfflineAssetsTaskTest.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2018 Adobe Systems Incorporated
All Rights Reserved.

NOTICE: All information contained herein is, and remains 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 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 Systems Incorporated.

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

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

	-- WF.oz_client.managed_catalog
local NmbOfflineAssets = require 'NmbOfflineAssets'
local NmbOfflineAssetsTask = require 'NmbOfflineAssetsTask'
local WFCatMockCatalog = require 'WFCatMockCatalog'
local WFCatAlbums = require 'WFCatAlbums'

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

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

local createFakeWFCatalog = WFCatMockCatalog.createFakeWFCatalog

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

local NmbOfflineAssetsTaskTest = {}

local kAsset1 = KSIdGenerator.uuidInLowercaseHex()

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

function NmbOfflineAssetsTaskTest.rxTestBasic( rxTest )

	rxTest:setTimeLimit( 10 )

	local fakeWFCatalog = createFakeWFCatalog( rxTest )

	local optArgs = {
		debugMode = true
	}

	local offlineAssetsTask = NmbOfflineAssetsTask( fakeWFCatalog, optArgs )

	local processedAssetIdStream = offlineAssetsTask:getProcessedAssetIdStream()

	local observer = rxTest:observe( processedAssetIdStream )

	local docStore = fakeWFCatalog:docStore()

	rxTest:expectSingleValue(

		docStore:setDocValue {
				_id = kAsset1,
				type = 'asset',
				subtype = 'image',
				captureDate = '2001',
				importSource = {
					filePath = '/path/',
					originalHeight = 150,
					originalWidth = 100,
				},
				_serverProvidedMetadata = {

					links = {
						[ '/rels/rendition_type/thumbnail2x' ] = { href = '/href/bogus/testing' }
					}

				}
			},

		':ignore:' )


	local albumId
	
	rxTest:expectOnlyCompleted(
		WFCatAlbums.createAlbum( fakeWFCatalog, 'My Album' )
			:map( function( _, globalAlbumId )
				albumId = globalAlbumId
				return albumId
			end )
			:takeLast( 0 )
	)

	rxTest:expectOnlyCompleted(
		WFCatAlbums.addAssetsToAlbum( fakeWFCatalog, albumId, { kAsset1 } )
	)

	rxTest:expectOnlyCompleted(
		NmbOfflineAssets.enableLocalAlbumStorage( fakeWFCatalog, { albumId }, true )
	)

	rxTest:expectSingleValue(
		fakeWFCatalog:docStore():docValue( albumId )
			:pluck( '_localOnly', 'isMarkedForOfflineUse' ),
		true
	)	

	observer:expectDataWithinTime( 3, { kAsset1, true } )

	rxTest:expectSingleValue(
		fakeWFCatalog:docStore():docValue( kAsset1 )
			:pluck( '_localOnly', 'isMarkedForOfflineUse' ),
		true
	)
	
	rxTest:expectOnlyCompleted(
		NmbOfflineAssets.disableLocalAlbumStorage( fakeWFCatalog, { albumId }, true )
	)

	rxTest:expectSingleValue(
		fakeWFCatalog:docStore():docValue( albumId )
			:pluck( '_localOnly', 'isMarkedForOfflineUse' ),
		nil
	)

	observer:expectDataWithinTime( 3, { kAsset1, false } )

	rxTest:expectSingleValue(
		fakeWFCatalog:docStore():docValue( kAsset1 )
			:pluck( '_localOnly', 'isMarkedForOfflineUse' ),
		nil
	)

	offlineAssetsTask:close()
	
end

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

function NmbOfflineAssetsTaskTest.rxTestMultipleAlbumsContainSameAsset( rxTest )

	rxTest:setTimeLimit( 10 )

	local fakeWFCatalog = createFakeWFCatalog( rxTest )

	local docStore = fakeWFCatalog:docStore()

	local optArgs = {
		debugMode = true
	}

	local offlineAssetsTask = NmbOfflineAssetsTask( fakeWFCatalog, optArgs )

	local processedAssetIdStream = offlineAssetsTask:getProcessedAssetIdStream()

	local observer = rxTest:observe( processedAssetIdStream )

	rxTest:expectSingleValue(

		docStore:setDocValue {
				_id = kAsset1,
				type = 'asset',
				subtype = 'image',
				captureDate = '2001',
				importSource = {
					filePath = '/path/',
					originalHeight = 150,
					originalWidth = 100,
				},
				_serverProvidedMetadata = {

					links = {
						[ '/rels/rendition_type/thumbnail2x' ] = { href = '/href/bogus/testing' }
					}

				}
			},

		':ignore:' )


	local albumId1
	
	rxTest:expectOnlyCompleted(
		WFCatAlbums.createAlbum( fakeWFCatalog, 'My Album' )
			:map( function( _, globalAlbumId )
				albumId1 = globalAlbumId
				return albumId1
			end )
			:takeLast( 0 )
	)

	local albumId2
	
	rxTest:expectOnlyCompleted(
		WFCatAlbums.createAlbum( fakeWFCatalog, 'My Album 2' )
			:map( function( _, globalAlbumId )
				albumId2 = globalAlbumId
				return albumId2
			end )
			:takeLast( 0 )
	)

	rxTest:expectOnlyCompleted(
		WFCatAlbums.addAssetsToAlbum( fakeWFCatalog, albumId1, { kAsset1 } )
	)

	rxTest:expectOnlyCompleted(
		WFCatAlbums.addAssetsToAlbum( fakeWFCatalog, albumId2, { kAsset1 } )
	)

	rxTest:expectSingleValue(
		fakeWFCatalog:docStore():docValue( kAsset1 )
			:pluck( '_localOnly', 'isMarkedForOfflineUse' ),
		nil
	)

	rxTest:expectOnlyCompleted(
		NmbOfflineAssets.enableLocalAlbumStorage( fakeWFCatalog, { albumId1 } )
	)

	observer:expectDataWithinTime( 3, { kAsset1, true } )

	rxTest:expectSingleValue(
		fakeWFCatalog:docStore():docValue( kAsset1 )
			:pluck( '_localOnly', 'isMarkedForOfflineUse' ),
		true
	)
	
	rxTest:expectOnlyCompleted(
		NmbOfflineAssets.enableLocalAlbumStorage( fakeWFCatalog, { albumId2 } )
	)

	rxTest:expectSingleValue(
		fakeWFCatalog:docStore():docValue( kAsset1 )
			:pluck( '_localOnly', 'isMarkedForOfflineUse' ),
		true
	)

	rxTest:expectOnlyCompleted(
		NmbOfflineAssets.disableLocalAlbumStorage( fakeWFCatalog, { albumId1 } )
	)

	rxTest:expectSingleValue(
		fakeWFCatalog:docStore():docValue( kAsset1 )
			:pluck( '_localOnly', 'isMarkedForOfflineUse' ),
		true
	)

	rxTest:expectOnlyCompleted(
		NmbOfflineAssets.disableLocalAlbumStorage( fakeWFCatalog, { albumId2 } )
	)

	observer:expectDataWithinTime( 3, { kAsset1, false } )

	rxTest:expectSingleValue(
		fakeWFCatalog:docStore():docValue( kAsset1 )
			:pluck( '_localOnly', 'isMarkedForOfflineUse' ),
		nil
	)

	offlineAssetsTask:close()

end

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

function NmbOfflineAssetsTaskTest.rxTestBulk_testNightly( rxTest )

	rxTest:setTimeLimit( 60 )

	local fakeWFCatalog = createFakeWFCatalog( rxTest )

	local optArgs = {
		debugMode = true
	}

	local offlineAssetsTask = NmbOfflineAssetsTask( fakeWFCatalog, optArgs )

	local processedAssetIds = {}

	local processedAssetIdStream = offlineAssetsTask:getProcessedAssetIdStream()

		:map( function( assetInfo )
		
			local assetId = assetInfo[ 1 ]
			local enabled = assetInfo[ 2 ]
		
			processedAssetIds[ assetId ] = enabled
		
			return processedAssetIds
		
		end )

	local observer = rxTest:observe( processedAssetIdStream )

	local docStore = fakeWFCatalog:docStore()

	local assetIds = {}

	for i = 1, 500, 1 do

		local assetId = KSIdGenerator.uuidInLowercaseHex()

		table.insert( assetIds, assetId )

		rxTest:expectSingleValue(

			docStore:setDocValue {
					_id = assetId,
					type = 'asset',
					subtype = 'image',
					captureDate = '2001',
					importSource = {
						filePath = '/path/',
						originalHeight = 150,
						originalWidth = 100,
					},
					_serverProvidedMetadata = {

						links = {
							[ '/rels/rendition_type/thumbnail2x' ] = { href = '/href/bogus/testing' }
						}

					}
				},

			':ignore:' )

	end
	
	local albumId
	
	rxTest:expectOnlyCompleted(
		WFCatAlbums.createAlbum( fakeWFCatalog, 'My Album' )
			:map( function( _, globalAlbumId )
				albumId = globalAlbumId
				return albumId
			end )
			:takeLast( 0 )
	)

	rxTest:expectOnlyCompleted(
		WFCatAlbums.addAssetsToAlbum( fakeWFCatalog, albumId, assetIds )
	)

	rxTest:expectOnlyCompleted(
		NmbOfflineAssets.enableLocalAlbumStorage( fakeWFCatalog, { albumId }, true )
	)

	rxTest:expectSingleValue(
		fakeWFCatalog:docStore():docValue( albumId )
			:pluck( '_localOnly', 'isMarkedForOfflineUse' ),
		true
	)	

	local expectedValue = {}
	
	for _, assetId in ipairs( assetIds ) do

		expectedValue[ assetId ] = true

	end

	observer:expectDataWithinTime( 30, expectedValue )

	for _, assetId in ipairs( assetIds ) do
		rxTest:expectSingleValue(
			fakeWFCatalog:docStore():docValue( assetId )
				:pluck( '_localOnly', 'isMarkedForOfflineUse' ),
			true
		)
	end
	
	rxTest:expectOnlyCompleted(
		NmbOfflineAssets.disableLocalAlbumStorage( fakeWFCatalog, { albumId }, true )
	)

	rxTest:expectSingleValue(
		fakeWFCatalog:docStore():docValue( albumId )
			:pluck( '_localOnly', 'isMarkedForOfflineUse' ),
		nil
	)

	for _, assetId in ipairs( assetIds ) do

		expectedValue[ assetId ] = false

	end

	observer:expectDataWithinTime( 30, expectedValue )

	for _, assetId in ipairs( assetIds ) do
		rxTest:expectSingleValue(
			fakeWFCatalog:docStore():docValue( assetId )
				:pluck( '_localOnly', 'isMarkedForOfflineUse' ),
			nil
		)
	end

	offlineAssetsTask:close()
	
end

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

return WFRxTestCase.wrapSuite( NmbOfflineAssetsTaskTest )
