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

WFCatStorageTest.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2016 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 KSIdGenerator = require 'KSIdGenerator'
local KSTableUtils = require 'KSTableUtils'

local WFRxTestCase = require 'WFRxTestCase'
local WFCatMockCatalog = require 'WFCatMockCatalog'
local WFCatTestSession = require 'WFCatTestSession'

local WFCatStorage = require 'WFCatStorage'

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

local WFCatStorageTest = {}

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

function WFCatStorageTest.rxTestCountDocsOverQuota( rxTest )
	
	-- create catalog and doc store
	rxTest:setTimeLimit( 5 )
	
	local catalog = WFCatMockCatalog.createFakeWFCatalog( rxTest )
	local docStore = catalog:docStore()
	
	local countUpdates = rxTest:observe(  WFCatStorage.countOverOzStorageQuota( catalog, 0.1 ) )
	
	rxTest:finally( function()
		countUpdates:dispose()
	end )
	
	countUpdates:expectData( 0 )
	
	local docId = '7206c3ae9a094d69861ee8983e95085d'
	
	-- create basic 'asset' doc that has the storage exceeded error
	rxTest:expectSingleValue( 
		docStore:setDocValue {
			_id = docId,
			type = 'asset',
			subtype = 'image',
			importSource = {
				filePath = '/path/',
				originalHeight = 150,
				originalWidth = 100,
			},
			_localOnly = { 
				ozError = { 
					subtype = 'StorageExceededError',
				}
			}
		},
		':ignore:' )
	
	countUpdates:expectDataWithinTime( 3,  1 )
	
	rxTest:expectSingleValue( 
		docStore:applyOverlay {
			_id = docId,
			_localOnly = {
				ozError = { _delete = true }
			}
		},
		':ignore:' )
		
	countUpdates:expectDataWithinTime( 3, 0 )
	
end

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

function WFCatStorageTest.rxTestDocsOverQuota( rxTest )

	-- create catalog and doc store
	rxTest:setTimeLimit( 5 )
	
	local catalog = WFCatMockCatalog.createFakeWFCatalog( rxTest )
	local docStore = catalog:docStore()
	
	local docUpdates = rxTest:observe(  WFCatStorage.docsOverOzStorageQuota( catalog, 0.1 ) )
	
	rxTest:finally( function()
		docUpdates:dispose()
	end )
	
	docUpdates:expectData( {} )
	
	local docId = '7206c3ae9a094d69861ee8983e95085d'
	
	-- create basic 'asset' doc that has the storage exceeded error
	rxTest:expectSingleValue( 
		docStore:setDocValue {
			_id = docId,
			type = 'asset',
			subtype = 'image',
			importSource = {
				filePath = '/path/',
				originalHeight = 150,
				originalWidth = 100,
			},
			_localOnly = { 
				ozError = { 
					subtype = 'StorageExceededError',
				}
			}
		},
		':ignore:' )
	
	docUpdates:expectDataWithinTime( 3,  { 1 } ) -- this is the local id not the global id
	
	rxTest:expectSingleValue( 
		docStore:applyOverlay {
			_id = docId,
			_localOnly = {
				ozError = { _delete = true }
			}
		},
		':ignore:' )
		
	docUpdates:expectDataWithinTime( 3, {} )	

end

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

function WFCatStorageTest.rxTestClearOverQuotaDocsWhenStorageChanges_testNightly( rxTest )

	rxTest:setTimeLimit( 120 )
	
	local session = WFCatTestSession( rxTest )
	
	local catalog
	
	rxTest:expectSingleValue(
		session:catalog()
			:tap( function( _catalog )
				catalog = _catalog
			end ),
		':ignore:' )
	
	
	local docStore = catalog:docStore()
	
	local userSynchronizer = require 'WFCatUserSynchronizer'( catalog:ozUser() )
	userSynchronizer:startContinuousUpdates()
	
	local docUpdates = rxTest:observe(  WFCatStorage.docsOverOzStorageQuota( catalog, 0.1 ) )
	
	rxTest:finally( function()
		userSynchronizer:close()
		docUpdates:dispose()
	end )
	
	docUpdates:expectData( {} )
	
	local docId = '7206c3ae9a094d69861ee8983e95085d'
	
	-- create basic 'asset' doc that has the storage exceeded error
	rxTest:expectSingleValue( 
		docStore:setDocValue {
			_id = docId,
			type = 'asset',
			subtype = 'image',
			importSource = {
				filePath = '/path/',
				originalHeight = 150,
				originalWidth = 100,
				fileSize = 12345,
			},
			_localOnly = { 
				ozError = { 
					subtype = 'StorageExceededError',
				}
			}
		},
		':ignore:' )
	
	docUpdates:expectDataWithinTime( 3,  { 1 } ) -- this is the local id not the global id
	
	-- since no test accounts should be over quota, starting the monitor should
	-- clear the test doc above of its error
	local wfCatStorage = WFCatStorage( catalog )
	rxTest:addCloseTarget( wfCatStorage )
	
	docUpdates:expectDataWithinTime( 90, {} )

end

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

function WFCatStorageTest.rxTestDocsOverQuota_Order( rxTest )

	rxTest:setTimeLimit( 5 )
	
	local catalog = WFCatMockCatalog.createFakeWFCatalog( rxTest )
	local docStore = catalog:docStore()
	
	local docUpdates = rxTest:observe( WFCatStorage.docsOverOzStorageQuota( catalog, 0.1 ) )
	
	rxTest:finally( function()
		docUpdates:dispose()
	end )
	
	docUpdates:expectData( {} )
	
	-- Create a number of documents, all with StorageExceededError errors.
	
	local assetIds = {}
	local nonAssetIds = {}
	
	for i=1, 10, 1 do
	
		local docId = KSIdGenerator.uuidInLowercaseHex()
		local localId = i
		
		if i % 2 == 0 then
	
			rxTest:waitFor( 
				docStore:setDocValue {
					_id = docId,
					type = 'asset',
					subtype = 'image',
					importSource = {
						filePath = '/path/',
						originalHeight = 150,
						originalWidth = 100,
					},
					_localOnly = { 
						ozError = { 
							subtype = 'StorageExceededError',
						}
					}
				} )
				
			
			assetIds[ #assetIds + 1 ] = localId
			
		else
		
			rxTest:waitFor( 
				docStore:setDocValue {
					_id = docId,
					type = 'version',
					subtype = 'edit',
					name = 'foo',
					asset = {
						id = KSIdGenerator.uuidInLowercaseHex(),
					},
					_localOnly = { 
						ozError = { 
							subtype = 'StorageExceededError',
						}
					}
				} )
				
			nonAssetIds[ #nonAssetIds + 1 ] = localId
		
		end
	
	end
	
	-- Verify that the asset document are listed before the non-asset documents.
	
	local expected = KSTableUtils.appendArray( {}, assetIds )
	expected = KSTableUtils.appendArray( expected, nonAssetIds )
	
	docUpdates:expectDataWithinTime( 3,  expected )

end

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

return WFRxTestCase.wrapSuite( 'WFCatStorageTest', WFCatStorageTest )
