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

ADOBE CONFIDENTIAL
------------------
Copyright 2015 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.

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

	-- WF.core.os
local WFPlatformInfo = require 'WFPlatformInfo'

if WFPlatformInfo.isiOS then
       return {}
end

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

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

	-- WF.oz_client.sync_engine
local WFOzSyncConstants = require 'WFOzSyncConstants'

	-- WF.lrmobile.models
local LrmCatalogTestHelper = require 'LrmCatalogTestHelper'

local LrmCoreInfoIndexDefinitions = require 'LrmCoreInfoIndexDefinitions'

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

local LrmCatalogIndexDefinitionsTest = {}

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

local catalog, docStore, indexStore

local TEST_TIMEOUT = 10

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

function LrmCatalogIndexDefinitionsTest.setUp()
	
end

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

function LrmCatalogIndexDefinitionsTest.tearDown()

end

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

local function makeAssetDoc()

	return { 
		_localOnly = {
			thumbnail2x = {
				md5 = 'md5_hash',
			},
			preview = {
				md5 = 'md5_hash',
			},
			proxy = {
				filePath = '/originals/foo.jpeg',
			},
		}
	}
	
end

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

-- @mark coreInfo table

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

function LrmCatalogIndexDefinitionsTest.rxTestCoreInfo_ignorePhotoWithoutRenditionsAndProxy( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	-- Add one "photo" to the doc store.

	local assetId = KSIdGenerator.uuidInLowercaseHex()

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			width = 30,
			height = 20,
			captureDate = '2012-08-15T15:22:29',
		},
		':ignore:' )
		
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			width = 30,
			height = 20,
			captureDate = '2012-08-15T15:22:29',
			_localOnly = {
				thumbnail2x = {
					md5 = 'foo',
				}
			}
		},
		':ignore:' )

		-- Query result should be empty because this photo did not
		-- contain a thumbnail reference.

	local obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT docId	FROM coreInfo]],
			quiesceUntilUpToDate = true
		} )
		
	obs:expectData(	{} )
		
end

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

function LrmCatalogIndexDefinitionsTest.rxTestCoreInfo_ImportedAssetWithReferencedMaster( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	local localUrl = KSIdGenerator.uuid()
	
		-- Add one "photo" to the doc store.
		
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			importSource = {
				originalWidth = 30,
				originalHeight = 20,
			},
			captureDate = '2012-08-15T15:22:29',
			_localOnly = {
				thumbnail2x = {
					md5 = 'md5_hash',
				},
				preview = {
					md5 = 'md5_hash',
				},
				localUrl = localUrl,
			},
		},
		':ignore:' )
		
	local obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT docId FROM coreInfo]],
			quiesceUntilUpToDate = true
		} )
		
	obs:expectData(
		{
			{ assetId }
		} )
		
end

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

function LrmCatalogIndexDefinitionsTest.rxTestCoreInfo_FullAssetSet( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )
	
	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )
	
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = KSIdGenerator.uuidInLowercaseHex(),
			userCreated = '2012-01-15T11:12:15',
			userUpdated = '2012-09-14T15:22:29',
			captureDate = '2012-08-15T15:22:29',
			_serverProvidedMetadata = {
				updated = '2012-09-15T15:22:29',
				importedByUser = {
					id = 'imported by someone',
				},
			},
			_localOnly = {
				thumbnail2x = {
					md5 = 'hash',
				},
				preview = {
					md5 = 'hash',
				},
				proxy = {
					filePath = 'originals/foo_proxy.jpeg',
				},
				localUrl = 'asset-url://file.dng',
			},
			importSource = {
				originalWidth = 30,
				originalHeight = 20,
				fileName = 'File01.dng',
				importedBy = 'iPhone 10S',
				importTimestamp = '2012-01-15T11:12:15',
				copyTimestamp = '2013-11-09',
			},
			reviews = {
				[ KSIdGenerator.uuidInLowercaseHex() ] = {
					flag = 'pick',
				},
			},
			ratings = {
				[ KSIdGenerator.uuidInLowercaseHex() ] = {
					rating = 5,
				},
			},
			xmp = {
					dc = {
					rights = 'Copyright',
				},
				exif = {
					ExposureTime = { 100, 1 },
					FNumber = { 100, 1 },
					ApertureValue = { 100, 1 },
					FocalLength = { 100, 1 },
					ISOSpeedRatings = 100,
				},
				tiff = {
					Make = 'Make',
					Model = 'Model',
				},
				aux = {
					Lens = 'Lens',
				}
			},
			develop = {
				croppedWidth = 25,
				croppedHeight = 20,
				xmpCameraRaw = '<xmp fooEdit=0 />'
			}
		},
		':ignore:' )

	local obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT 	aspectRatio, captureDate, displayDate,
						copyTimestamp, thumbnailMD5, importedBy, 
						contentType, wasDeveloped, croppedWidth, 
						croppedHeight, fileName, modifiedDate, 
						width, height, apertureValue, isoSpeedRatings, 
						exposureTime, cameraMaker, cameraModel, flag,
						rating, copyright, isVideo, localUrl, fnumber,
						importedByUser, syncStatus
				FROM coreInfo]],
				quiesceUntilUpToDate = true
		} )
	
	obs:expectDataWithinTime( 2, {
			{
				1.25, 							-- aspect ratio
				'2012-08-15T15:22:29', 			-- capture date
				'2012-08-15',					-- displayDate
				'2013-11-09',					-- copy timestamp
				'hash',							-- thumbnailMD5
				'iPhone 10S',					-- importedBy
				1000,							-- contentType
				1,								-- wasDeveloped
				25,								-- croppedWidth
				20,								-- croppedHeight
				'File01.dng',					-- fileName
				'2012-09-14T15:22:29',			-- modifiedDate
				30,								-- width
				20,								-- height
				'100.0',						-- apertureValue
				'100',							-- isoSpeedRatings
				'100',							-- exposureTime
				'Make',							-- cameraMaker
				'Model',						-- cameraModel
				'pick',							-- flag
				5,								-- rating
				'Copyright',					-- copyright
				0,								-- isVideo
				'asset-url://file.dng',			-- localUrl
				'100.0',						-- fnumber
				'imported by someone',			-- importedByUser
				1,								-- syncStatus
			}
		} )
end

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

function LrmCatalogIndexDefinitionsTest.rxTestCoreInfo_VideoType( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'video',
			_id = KSIdGenerator.uuidInLowercaseHex(),
			_localOnly = {
				thumbnail2x = {
					md5 = 'hash',
				},
				preview = {
					md5 = 'hash',
				},
				proxy = {
					filePath = 'originals/foo_proxy.jpeg',
				},
			},
			video = {
			},
			importSource = {
				originalWidth = 30,
				originalHeight = 20,
				contentType = 'video/mp4',
			}
		},
		':ignore:' )
	
	local obs = rxTest:observe( indexStore:query{ sql =
			[[	
				SELECT 
					isVideo, contentType
				FROM 
					coreInfo
			]],
			quiesceUntilUpToDate = true
		} )

	local WFPlatformInfo = require 'WFPlatformInfo'
	if WFPlatformInfo.isAndroid then

		obs:expectData(
			{
			} )

	else

		obs:expectData(
			{
				{
					1,
					2001
				}
			} )

	end

end

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

function LrmCatalogIndexDefinitionsTest.rxTestCoreInfo_RatedAssetFromAnonymous( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
		-- Add one "photo" to the doc store.
		
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			importSource = {
				originalWidth = 30,
				originalHeight = 20,
			},
			captureDate = '2012-08-15T15:22:29',
			_localOnly = {
				thumbnail2x = {
					md5 = 'md5_hash',
				},
				preview = {
					md5 = 'md5_hash',
				},
				localUrl = KSIdGenerator.uuid(),
			},
			ratings = {
				[ WFOzSyncConstants.kGlobalDocumentId ] = {
					rating = 5,
				}
			}
		},
		':ignore:' )

	local obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT docId, rating FROM coreInfo]],
			quiesceUntilUpToDate = true
		} )
		
	obs:expectData(	{
			{ 
				assetId, 
				5 
			}
		} )
		
end

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

function LrmCatalogIndexDefinitionsTest.rxTestCoreInfo_ModifiedDate( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	local assetId2 = KSIdGenerator.uuidInLowercaseHex()

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			importSource = {
				originalWidth = 30,
				originalHeight = 20,
				fileName = 'file1',
			},
			captureDate = '2012-08-15T15:22:29',
			_localOnly = {
				thumbnail2x = {
					md5 = 'md5_hash',
				},
				preview = {
					md5 = 'md5_hash',
				},
				localUrl = KSIdGenerator.uuid(),
			},
		},
		':ignore:' )

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId2,
			captureDate = '2012-08-15T15:22:29',
			importSource = {
				originalWidth = 30,
				originalHeight = 20,
				importTimestamp = '2015-08-15',
				fileName = 'file2',
			},
			_localOnly = {
				thumbnail2x = {
					md5 = 'md5_hash',
				},
				preview = {
					md5 = 'md5_hash',
				},
				localUrl = KSIdGenerator.uuid(),
			},
		},
		':ignore:' )
		
	
	local obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT docId FROM coreInfo ORDER BY modifiedDate DESC, captureDate DESC, fileName DESC]],
			quiesceUntilUpToDate = true
		} )
	
	obs:expectData(	{
			{ 
				assetId2
			},
			{
				assetId,
			}
		} )
		
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			userUpdated = '2015-08-17',
		},
		':ignore:' )

	obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT docId FROM coreInfo ORDER BY modifiedDate DESC, fileName DESC]],
			quiesceUntilUpToDate = true
		} )
	
	obs:expectData(	{
			{ 
				assetId,
			},
			{
				assetId2,
			}
		} )
		
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId2,
			userUpdated = '2015-08-18',
		},
		':ignore:' )

	obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT docId FROM coreInfo ORDER BY modifiedDate DESC, fileName DESC]],
			quiesceUntilUpToDate = true
		} )
	
	obs:expectData(	{
			{ 
				assetId2,
			},
			{
				assetId,
			}
		} )
		
end

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

function LrmCatalogIndexDefinitionsTest.rxTestCoreInfoForAdobeCameraImages( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
		-- Add one "photo" to the doc store.
		
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			importSource = {
				originalWidth = 30,
				originalHeight = 20,
			},
			captureDate = '2012-08-15T15:22:29',
			_localOnly = {
				thumbnail2x = {
					md5 = 'md5_hash',
				},
				preview = {
					md5 = 'md5_hash',
				},
				localUrl = KSIdGenerator.uuid(),
			},
		},
		':ignore:' )

	local obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT docId, isCapturedWithAdobeCamera FROM coreInfo]],
			quiesceUntilUpToDate = true
		} )
		
	obs:expectData(	{
			{ 
				assetId, 
				0
			}
		} )
		
	rxTest:expectSingleValue( docStore:applyOverlay {
			_id = assetId,
			xmp = {
				xmp = {
					CreatorTool = 'Adobe Camera 1.0',
				},
			}
		},
		':ignore:' )
		
	obs:expectData(	{
			{ 
				assetId, 
				1
			}
		} )
		
	rxTest:expectSingleValue( docStore:applyOverlay {
			_id = assetId,
			xmp = {
				xmp = {
					CreatorTool = 5,
				},
			}
		},
		':ignore:' )
		
	obs:expectData(	{
			{ 
				assetId, 
				0
			}
		} )
		
	rxTest:expectSingleValue( docStore:applyOverlay {
			_id = assetId,
			xmp = {
				xmp = {
					CreatorTool = 'Adobe Camera    3',
				},
			}
		},
		':ignore:' )
		
	obs:expectData(	{
			{ 
				assetId, 
				1
			}
		} )
		
end

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

function LrmCatalogIndexDefinitionsTest.rxTestCoreInfoIsDisplayable( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	-- asset without local binary and _serverProvidedMetadata links
	rxTest:expectEqual( false, LrmCoreInfoIndexDefinitions.assetIsDisplayable(
		{
			type = 'asset',
			subtype = 'image',
			_id = assetId
		}))
	
	-- asset has local master
	rxTest:expectEqual( true, LrmCoreInfoIndexDefinitions.assetIsDisplayable(
		{
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			_localOnly = {
				localUrl = KSIdGenerator.uuid(),
			}
		}))
		
	rxTest:expectEqual( true, LrmCoreInfoIndexDefinitions.assetIsDisplayable(
		{
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			_localOnly = {
				originalFilePath = "/originals/file.jpeg"
			}
		}))
		
	rxTest:expectEqual( true, LrmCoreInfoIndexDefinitions.assetIsDisplayable(
		{
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			_localOnly = {
				latestOriginal = {
					filePath = "/originals/file.jpeg"
				}
			}
		}))
		
	-- asset has local proxy 
	rxTest:expectEqual( true, LrmCoreInfoIndexDefinitions.assetIsDisplayable(
		{
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			_localOnly = {
				proxy = {
					filePath = "/originals/file_proxy.jpeg"
				}
			}
		}))
		
	-- asset has _serverProvidedMetadata links
	rxTest:expectEqual( true, LrmCoreInfoIndexDefinitions.assetIsDisplayable(
		{
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			_serverProvidedMetadata = {
				links = {
					['/rels/proxy_type/2560'] = {
						href = 'catalogs/assets/revisions/proxies'
					},
					['/rels/master'] = {
						href = 'catalogs/assets/revisions/master'
					}
				}
			}
		}))
		
	-- Android doesn't support video
	local videoIsDisplayable = true
	if WFPlatformInfo.isAndroid then
		videoIsDisplayable = false
	end
	rxTest:expectEqual( videoIsDisplayable, LrmCoreInfoIndexDefinitions.assetIsDisplayable(
		{
			type = 'asset',
			subtype = 'video',
			_id = assetId,
			_serverProvidedMetadata = {
				links = {
					['/rels/proxy_type/2560'] = {
						href = 'catalogs/assets/revisions/proxies'
					},
					['/rels/master'] = {
						href = 'catalogs/assets/revisions/master'
					}
				}
			}
		}))
		
	-- Only support type asset
	rxTest:expectEqual( false, LrmCoreInfoIndexDefinitions.assetIsDisplayable(
		{
			type = 'album',
			subtype = 'collection',
			_id = KSIdGenerator.uuidInLowercaseHex(),
			name = 'collection 2015',
			updated = '2012-08-15T15:22:29',
		}))
end

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

-- @mark album_asset table

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

function LrmCatalogIndexDefinitionsTest.rxTestAlbumAssets( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local albumId = KSIdGenerator.uuidInLowercaseHex()
	local assetId = KSIdGenerator.uuidInLowercaseHex()
	local albumAssetId = KSIdGenerator.uuidInLowercaseHex()
	
	local docValue = makeAssetDoc()
	
	-- add asset
	
	docValue = WFTableMerge.applyOverlay( docValue, {
		type = 'asset',
		subtype = 'image',
		_id = assetId,
		importSource = {
			originalWidth = 200,
			originalHeight = 100,
		}
	} )
	
	rxTest:expectSingleValue( docStore:applyOverlay( docValue ),
		':ignore:' )
		
		
	-- add album_asset
	
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'album_asset',
			_id = albumAssetId,
			album = {
				id = albumId,
			},
			asset = {
				id = assetId,
			}
		},
		':ignore:' )
	
	-- verify result in index store
	
	local obs = rxTest:observe( indexStore:query { 
		sql = [[SELECT 
					coreInfo.docId 
				FROM 
					coreInfo 
				LEFT JOIN 
					album_asset 
				ON 
					album_asset.assetId == coreInfo.docId 
				WHERE 
					albumId == ?]],
		quiesceUntilUpToDate = true,
		albumId
	} )
	
	obs:expectData( {
		{ assetId }
	} )
		
end

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

-- @mark albums table

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

function LrmCatalogIndexDefinitionsTest.rxTestAlbums( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local albumId1 = KSIdGenerator.uuidInLowercaseHex()
	local albumId2 = KSIdGenerator.uuidInLowercaseHex()
	local folderId1 = KSIdGenerator.uuidInLowercaseHex()
	local folderId2 = KSIdGenerator.uuidInLowercaseHex()
	local coverId = KSIdGenerator.uuidInLowercaseHex()
	
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'album',
			subtype = 'collection',
			_id = albumId1,
			name = 'collection 2015',
			updated = '2012-08-15T15:22:29',
			-- parent not set
		},
		':ignore:' )
		
	-- Add two folders to the doc store.

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'album',
			subtype = 'collection_set',
			_id = folderId1,
			name = 'Folder 1',
			updated = '2017-07-20T15:22:29',
			-- parent not set
		},
		':ignore:' )

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'album',
			subtype = 'collection_set',
			_id = folderId2,
			name = 'Folder 2',
			updated = '2017-07-20T15:40:29',
			parent = {
				id = folderId1
			}
		},
		':ignore:' )

	-- Add another album to the doc store.

	rxTest:expectSingleValue ( docStore:applyOverlay {
			type = 'album',
			subtype = 'collection',
			_id = albumId2,
			name = '   Collection 2014   ',
			updated = '2012-08-15T15:22:29',
			parent = {
				id = folderId2
			}
		},
		':ignore:' )

	local obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT docId, name, nameLC, updateTimeStamp, localTimeStamp, useOffline, coverId, parentId, subtype FROM albums]],
			quiesceUntilUpToDate = true
		} )
	
	obs:expectData( {
			{
				albumId1,
				'collection 2015',
				'collection 2015',
				'2012-08-15T15:22:29',
				nil,
				0,
				nil,
				'root',
				'collection'
			},
			{
				folderId1,
				'Folder 1',
				'folder 1',
				'2017-07-20T15:22:29',
				nil,
				0,
				nil,
				'root',
				'collection_set'
			},
			{
				folderId2,
				'Folder 2',
				'folder 2',
				'2017-07-20T15:40:29',
				nil,
				0,
				nil,
				folderId1,
				'collection_set'
			},
			{
				albumId2,
				'   Collection 2014   ',
				'collection 2014',
				'2012-08-15T15:22:29',
				nil,
				0,
				nil,
				folderId2,
				'collection'
			}
		} )
		
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'album',
			subtype = 'collection',
			_id = albumId2,
			_localOnly = {
				useOffline = true,
				updateTimeStamp = '2015-11-09',
			},
			updated = { _delete = true },
		},
		':ignore:' )

	obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT docId, useOffline, localTimeStamp, updateTimeStamp FROM albums WHERE docId = ?]],
			albumId2,
			quiesceUntilUpToDate = true
		} )
		
	obs:expectData( { 
			{
				albumId2,
				1,
				'2015-11-09',
				'2015-11-09'
			} 
		} )
		
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'album',
			subtype = 'collection',
			_id = albumId2,
			_localOnly = {
				useOffline = true,
				updateTimeStamp = { _delete = true },
			},
			updated = { _delete = true },
			_serverProvidedMetadata = {
				updated = '2015-10-27',
			},
		},
		':ignore:' )

	obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT docId, useOffline, localTimeStamp, updateTimeStamp FROM albums WHERE docId = ?]],
			albumId2,
			quiesceUntilUpToDate = true
		} )
		
	obs:expectData(	{ 
			{
				albumId2,
				1,
				nil,
				'2015-10-27'
			} 
		} )
	
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'album',
			subtype = 'collection',
			_id = albumId2,
			cover = {
				id = coverId,
			}
		},
		':ignore:' )
		
	obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT docId, coverId FROM albums WHERE docId = ?]],
			albumId2,
			quiesceUntilUpToDate = true
		} )
	
	obs:expectData(	{
			{
				albumId2,
				coverId,
			} 
		} )

end

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

function LrmCatalogIndexDefinitionsTest.rxTestHideInOrganize( rxTest )

	rxTest:setTimeLimit( 40 )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local albumId1 = KSIdGenerator.uuidInLowercaseHex()
	
	rxTest:expectSingleValue( docStore:applyOverlay {
		type = 'album',
		subtype = 'collection',
		_id = albumId1,
		name = 'collection 2015',
		updated = '2012-08-15T15:22:29',
		hideInOrganize = false
		
	},
	':ignore:' )
	
	local obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT docId, hideInOrganize FROM albums]],
			quiesceUntilUpToDate = true
		}
		)
		
	obs:expectData( {
		{
			albumId1, 0
		}
	} )
	
	rxTest:expectSingleValue( docStore:applyOverlay {
		_id = albumId1,
		hideInOrganize = true
		
	},
	':ignore:' )
	
	obs:expectData( {
		{
			albumId1, 1
		}
	} )
	
	rxTest:expectSingleValue( docStore:applyOverlay {
		_id = albumId1,
		hideInOrganize = { _delete = true }
		
	},
	':ignore:' )
	
	obs:expectData( {
		{
			albumId1, 0
		}
	} )

end

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

-- @mark flags table

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

function LrmCatalogIndexDefinitionsTest.rxTestFlags( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	local userId = KSIdGenerator.uuidInLowercaseHex()

	local docValue = makeAssetDoc()

	docValue = WFTableMerge.applyOverlay( docValue, {
		type = 'asset',
		subtype = 'image',
		_id = assetId,
	} )

	rxTest:expectSingleValue( docStore:applyOverlay( docValue ),
		':ignore:' )

	local obs = rxTest:observe( indexStore:query{ sql =
	[[SELECT docId, flag FROM coreInfo]],
		quiesceUntilUpToDate = true
	} )

	obs:expectData( {
		{
			assetId,
			'unflagged'
		}
	} )


	docValue = makeAssetDoc()

	docValue = WFTableMerge.applyOverlay( docValue, {

		type = 'asset',
		subtype = 'image',
		_id = assetId,

		reviews = {
			[ userId ] = {
				date = '2015-11-09',
				flag = 'pick',
			}
		}

	} )

	rxTest:expectSingleValue( docStore:applyOverlay( docValue ),
		':ignore:')

	obs = rxTest:observe( indexStore:query{ sql =
	[[SELECT docId, flag FROM coreInfo]],
		quiesceUntilUpToDate = true
	} )

	obs:expectData( {
		{
			assetId,
			'pick'
		}
	} )

end

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

-- @mark space 

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

function LrmCatalogIndexDefinitionsTest.rxTestSpace( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local spaceId = KSIdGenerator.uuidInLowercaseHex()
	
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'space',
			subtype = 'shared',
			_id = spaceId,
			private = false,
			download = false,
			updated = '2015-11-09',
			created = '2015-11-09'
		},
		':ignore:' )

	local obs = rxTest:observe( indexStore:query{ sql =
				[[SELECT created, updateTimeStamp, private, download FROM space WHERE isDeleted == 0]],
				quiesceUntilUpToDate = true
			} )

	obs:expectData( {
			{
				'2015-11-09',
				'2015-11-09',
				0,
				0
			},
		} )
		
		
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'space',
			subtype = 'shared',
			_id = spaceId,
			updated = '2015-12-09',
			private = true,
		},
		':ignore:' )
		
	obs = rxTest:observe( indexStore:query{ sql =
				[[SELECT created, updateTimeStamp, private, download FROM space WHERE isDeleted == 0]],
				quiesceUntilUpToDate = true
			} )
		
	obs:expectData( {
			{
				'2015-11-09',
				'2015-12-09',
				1,
				0
			},
		} )

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'space',
			subtype = 'shared',
			_id = spaceId,
			created = { _delete = true },
			_localOnly = {
				created = '2014-01-10',
			}
		},
		':ignore:' )
		

	obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT created, updateTimeStamp, private, download FROM space WHERE isDeleted == 0]],
			quiesceUntilUpToDate = true
		} )

	obs:expectData( {
			{
				'2014-01-10',
				'2015-12-09',
				1,
				0
			},
		} )
	
end

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

-- @mark persons

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

function LrmCatalogIndexDefinitionsTest.rxTestPersons( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local personId = KSIdGenerator.uuidInLowercaseHex()
	local personId2 = KSIdGenerator.uuidInLowercaseHex()

	rxTest:expectSingleValue( docStore:applyOverlay {
			_id = personId,
			type = 'asset',
			subtype = 'person',
			_serverProvidedMetadata = {
				links = {
					['/rels/rendition_type/thumbnail2x'] = {
						href = '/v2/abc',
					}
				}
			},
			name = 'foo',
			hidden = true,
			primary = 'abc',
		},
		':ignore:' )
		
	rxTest:expectSingleValue( docStore:applyOverlay {
			_id = personId2,
			type = 'asset',
			subtype = 'person',
			_serverProvidedMetadata = {
				links = {
					['/rels/rendition_type/thumbnail2x'] = {
						href = '/v2/abc',
					}
				}
			},
		},
		':ignore:' )

	local obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT docId, name, hidden, primaryId, thumnailLink FROM persons ORDER BY name]],
			quiesceUntilUpToDate = true
		} )

	obs:expectData( {
			{
				personId2,
				'',
				0,
				'',
				'/v2/abc'
			},
			{
				personId,
				'foo',
				1,
				'abc',
				'/v2/abc'
			},
		} )
		
end

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

-- @mark avatarCacheReferences

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

function LrmCatalogIndexDefinitionsTest.rxTestCachedAvatars( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local feedbackuserId = KSIdGenerator.uuidInLowercaseHex()

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'feedbackuser',
			_id = feedbackuserId,
			avatars = {
				small2x = {
					md5 = 'md5-hash',
					size = 1000,
					epoch = 1,
				}
			}
		},
		':ignore:' )
		
	local obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT docId, md5, avatarType, size, epoch FROM avatarCacheReferences]],
			quiesceUntilUpToDate = true
		} )

	obs:expectData( {
			{
				feedbackuserId,
				'md5-hash',
				'small2x',
				1000,
				1
			},
		} )
		
end

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

-- @mark renditionRevision

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

function LrmCatalogIndexDefinitionsTest.rxTestRenditionRevisions_basic( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local assetId = KSIdGenerator.uuidInLowercaseHex()

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			_localOnly = {
				thumbnail2x = {},
				preview = {},
			}
		},
		':ignore:' )

	local obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT renditionName FROM renditionRevisions ORDER BY renditionName]],
			quiesceUntilUpToDate = true
		} )

	obs:expectData( {} )
	
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			_localOnly = {
				thumbnail2x = {
					revId = '16b97d9d9e3042d09633c3878622d48b',
					renditionId = '835c23790d534b28b8b7bb99740d13bb',
				},
				preview = {
					revId = '16b97d9d9e3042d09633c3878622d48c',
					renditionId = '835c23790d534b28b8b7bb99740d13bc',
				},
			},
			_serverProvidedMetadata = {
				links = {
					[ '/rels/rendition_type/thumbnail2x' ] = {
						href = 'catalogs/f50509f546184519afa38d4e55e442fc/assets/496e4bec7eff1bee558b4760ae00efa3/revisions/16b97d9d9e3042d09633c3878622d48a/renditions/835c23790d534b28b8b7bb99740d13ba',
					},
					[ '/rels/rendition_type/2048' ] = {
						href = 'catalogs/f50509f546184519afa38d4e55e442fc/assets/496e4bec7eff1bee558b4760ae00efa3/revisions/16b97d9d9e3042d09633c3878622d48a/renditions/835c23790d534b28b8b7bb99740d13ba',
					},
					[ '/rels/proxy_type/2560' ] = {
						href = 'catalogs/f50509f546184519afa38d4e55e442fc/assets/496e4bec7eff1bee558b4760ae00efa3/revisions/16b97d9d9e3042d09633c3878622d48a/proxies/a5429e4c4bc7402bb8fb9102dbde4317'
					}
				},
			}
		},
		':ignore:' )
		
	obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT renditionName FROM renditionRevisions ORDER BY renditionName]],
			quiesceUntilUpToDate = true
		} )
		
	obs:expectData(	{
			{
				'preview',
			},
			{
				'proxy',
			},
			{
				'proxyWithoutMaster',
			},
			{
				'thumbnail2x',
			}
		} )
		
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			_localOnly = {
				thumbnail2x = {
					md5 = '<hash>',
					revId = '16b97d9d9e3042d09633c3878622d48a',
					renditionId = '835c23790d534b28b8b7bb99740d13ba',
				},
				preview = {
					md5 = '<hash>',
					revId = '16b97d9d9e3042d09633c3878622d48a',
					renditionId = '835c23790d534b28b8b7bb99740d13ba',
				},
				proxy = {
					filePath = '<path>',
				}
			}
		},
		':ignore:' )

	obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT renditionName FROM renditionRevisions ORDER BY renditionName]],
			quiesceUntilUpToDate = true
		} )

	obs:expectData( {} )
	
end

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

function LrmCatalogIndexDefinitionsTest.rxTestRenditionRevisions_preferMaster( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			_localOnly = {
				thumbnail2x = {
					revId = '16b97d9d9e3042d09633c3878622d48b',
					renditionId = '835c23790d534b28b8b7bb99740d13bb',
				},
				preview = {
					revId = '16b97d9d9e3042d09633c3878622d48c',
					renditionId = '835c23790d534b28b8b7bb99740d13bc',
				},
			},
			_serverProvidedMetadata = {
				links = {
					[ '/rels/rendition_type/thumbnail2x' ] = {
						href = 'catalogs/f50509f546184519afa38d4e55e442fc/assets/496e4bec7eff1bee558b4760ae00efa3/revisions/16b97d9d9e3042d09633c3878622d48a/renditions/835c23790d534b28b8b7bb99740d13ba',
					},
					[ '/rels/rendition_type/2048' ] = {
						href = 'catalogs/f50509f546184519afa38d4e55e442fc/assets/496e4bec7eff1bee558b4760ae00efa3/revisions/16b97d9d9e3042d09633c3878622d48a/renditions/835c23790d534b28b8b7bb99740d13ba',
					},
					[ '/rels/proxy_type/2560' ] = {
						href = 'catalogs/f50509f546184519afa38d4e55e442fc/assets/496e4bec7eff1bee558b4760ae00efa3/revisions/16b97d9d9e3042d09633c3878622d48a/proxies/a5429e4c4bc7402bb8fb9102dbde4317'
					},
					[ '/rels/master' ] = {
						href = 'catalogs/f50509f546184519afa38d4e55e442fc/assets/496e4bec7eff1bee558b4760ae00efa3/revisions/16b97d9d9e3042d09633c3878622d48a/master'
					}
				},
			}
		},
		':ignore:' )

	local obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT renditionName FROM renditionRevisions ORDER BY renditionName]],
			quiesceUntilUpToDate = true
		} )

	obs:expectData( {
			{
				'master',
			},
			{
				'preview',
			},
			{
				'proxy',
			},
			{
				'thumbnail2x',
			}
		} )

	rxTest:expectSingleValue( docStore:applyOverlay {
				type = 'asset',
				subtype = 'image',
				_id = assetId,
				importSource = {
					fileSize = 4000000,
				}
			},
			':ignore:' )

	obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT renditionName FROM renditionRevisions ORDER BY renditionName]],
			quiesceUntilUpToDate = true
		} )


	obs:expectData( {
			{
				'master',
			},
			{
				'preview',
			},
			{
				'proxy',
			},
			{
				'thumbnail2x',
			}
		} )
	
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			doctype = 'image',
			_id = assetId,
			_localOnly = {
				thumbnail2x = {
					md5 = '<hash>',
					revId = '16b97d9d9e3042d09633c3878622d48a',
					renditionId = '835c23790d534b28b8b7bb99740d13ba',
				},
				preview = {
					md5 = '<hash>',
					revId = '16b97d9d9e3042d09633c3878622d48a',
					renditionId = '835c23790d534b28b8b7bb99740d13ba',
				},
				originalFilePath = '/var/foo/...',
			}
		},
		':ignore:' )

	obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT renditionName FROM renditionRevisions ORDER BY renditionName]],
			quiesceUntilUpToDate = true
		} )

	obs:expectData( {
		{
			'proxy',
		},
	} )
		
end

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

if not WFPlatformInfo.isAndroid then

	-- Disabling this test for Android as we does have support for videos into the indexStore

function LrmCatalogIndexDefinitionsTest.rxTestRenditionRevisions_masterAndVideo( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local assetId = KSIdGenerator.uuidInLowercaseHex()

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'video',
			_id = assetId,
			importSource = {
				fileSize = 400000,
			},
			_localOnly = {
				thumbnail2x = {
					md5 = '<hash>',
				},
				preview = {
					md5 = '<hash>',
				},
			},
			_serverProvidedMetadata = {
				links = {
					[ '/rels/master' ] = {
						href = 'catalogs/f50509f546184519afa38d4e55e442fc/assets/496e4bec7eff1bee558b4760ae00efa3/revisions/16b97d9d9e3042d09633c3878622d48a/master',
					},
				}
			}
		},
		':ignore:' )

	local obs = rxTest:observe( indexStore:query { sql =
			[[SELECT renditionName, size FROM renditionRevisions ORDER BY renditionName]],
			quiesceUntilUpToDate = true
		} )
		
	obs:expectData( { { 'master', 400000 } } )

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'video',
			_id = assetId,
			importSource = {
				contentType = 'video/mp4',
			}
		},
		':ignore:' )

	obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT renditionName FROM renditionRevisions ORDER BY renditionName]],
			quiesceUntilUpToDate = true
		} )
		
	obs:expectData( {} )

end

end
--------------------------------------------------------------------------------

-- @mark assetProfileLink

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

function LrmCatalogIndexDefinitionsTest.rxTestAssetProfileLink( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local assetId = KSIdGenerator.uuidInLowercaseHex()

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			_localOnly = {
				thumbnail2x = {
					md5 = 'hash'
				},
				preview = {
					md5 = 'hash',
				},
				proxy = {
					filePath = 'originals/foo_proxy.jpeg',
				},
			},
			develop = {
				profiles = {
					camera = {
						href = '/v2/foo/master',
						filename = 'Adobe Standard.dcp',
					}
				}
			}
		},
		':ignore:' )

	local obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT subtype, fileName, masterUrl, uniqueId FROM assetProfileLinks]],
			quiesceUntilUpToDate = true
		} )

	obs:expectData( {
			{
				'camera',
				'Adobe Standard.dcp',
				'/v2/foo/master',
				'/v2/foo/master',
			}
		} )
	
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			develop = {
				profiles = {
					lens = {
						href = '/v2/foo/master',
						filename = 'Adobe Standard.lcp',
						
					}
				}
			}
		},
		':ignore:' )

	obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT subtype, fileName, masterUrl, uniqueId FROM assetProfileLinks ORDER BY subtype]],
			quiesceUntilUpToDate = true
		} )

	obs:expectData( {
			{
				'camera',
				'Adobe Standard.dcp',
				'/v2/foo/master',
				'/v2/foo/master',
			},
			{
				'lens',
				'Adobe Standard.lcp',
				'/v2/foo/master',
				'/v2/foo/master',
			}
		} )

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			develop = {
				profiles = {
					lens = {
						href = 'foo/master',
						filename = 'Adobe Standard.lcp',
						
					}
				}
			}
		},
		':ignore:' )

	obs = rxTest:observe( indexStore:query{ sql =
			'SELECT subtype, fileName, masterUrl, uniqueId FROM assetProfileLinks ORDER BY subtype',
			quiesceUntilUpToDate = true
		} )
	
	obs:expectData( {
			{
				'camera',
				'Adobe Standard.dcp',
				'/v2/foo/master',
				'/v2/foo/master',
			},
		} )		
	
	-- test invalid lens profile href
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			develop = {
				profiles = {
					lens = {
						href = 'foo/master',
						filename = { _delete = true }
					}
				}
			}
		},
		':ignore:' )
	
	obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT subtype, fileName, masterUrl, uniqueId FROM assetProfileLinks ORDER BY subtype]],
			quiesceUntilUpToDate = true
		} )

	obs:expectData( {
			{
				'camera',
				'Adobe Standard.dcp',
				'/v2/foo/master',
				'/v2/foo/master',
			},
		} )
	
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			develop = {
				profiles = {
					camera = {
						_delete = true,
					}
				}
			}
		},
		':ignore:' )
		
	obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT subtype, fileName, masterUrl, uniqueId FROM assetProfileLinks ORDER BY subtype]],
			quiesceUntilUpToDate = true
		} )
		
	obs:expectData( {} )
	
end

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

-- @mark profileRegistration

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

function LrmCatalogIndexDefinitionsTest.rxTestProfileRegistration( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'profile',
			_id = KSIdGenerator.uuidInLowercaseHex(),
			_localOnly = {
				subtype = 'camera',
				fileName = 'Adobe Standard Camera Landscape.dcp',
				uniqueId = 'foo/master',
			}
		},
		':ignore:' )
		
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'profile',
			_id = KSIdGenerator.uuidInLowercaseHex(),
			_localOnly = {
				subtype = 'lens',
				fileName = 'Nikon D3200.lcp',
				uniqueId = 'foo/master',
			}
		},
		':ignore:' )

	local obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT subtype, fileName, uniqueId FROM profileRegistration ORDER BY subtype]],
			quiesceUntilUpToDate = true
		} )
	
	obs:expectData( {
			{
				'camera',
				'Adobe Standard Camera Landscape.dcp',
				'foo/master'
			},
			{
				'lens',
				'Nikon D3200.lcp',
				'foo/master'
			},
		} )
		
end

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

-- @mark importSource

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

function LrmCatalogIndexDefinitionsTest.rxTestImportSource_withLocalUrl( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local assetId = KSIdGenerator.uuidInLowercaseHex()

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			_localOnly = {
				localUrl = '1234',
			},
			importSource = {
				sha256 = '5678',
			}
		},
		':ignore:' )

	local obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT localUrl, sha256 FROM coreInfo]],
			quiesceUntilUpToDate = true
		} )
	
	obs:expectData( {
			{
				'1234',
				'5678',
			},
		} )
	
	--[[ TODO [immisch 2016-04-18]: This test fails, because the new docstore does not allow the deletion of 
	  _localOnly:
	
		\b Important: The top-level key \c _localOnly gets special handling. If
		no value is provided for this key, any previous value is left in place.
		This behavior does not apply to any other key. This does imply that you
		can not delete any existing \c _localOnly entry in the document.
	
	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			_localOnly = {
				_delete = true,
			}
		},
		':ignore:' )

	obs = rxTest:observe( indexStore:query{ sql =
			'SELECT localUrl FROM importSource',
			quiesceUntilUpToDate = true
		} )
	
	obs:expectData( {
			{},
		} )

	]]--

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'image',
			_id = assetId,
			_localOnly = {
				localUrl = '9876',
			},
			importSource = {
				_delete = true,
			}
		},
		':ignore:' )

	obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT localUrl, sha256 FROM coreInfo]],
			quiesceUntilUpToDate = true
		},
		':ignore:'
 	)
	
	obs:expectData( {
			{ '9876' },
		} )
		
end

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

-- @mark presetsProfiles

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

function LrmCatalogIndexDefinitionsTest.rxTestPresetsAndProfiles( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	local assetId1 = KSIdGenerator.uuidInLowercaseHex()
	local assetId2 = KSIdGenerator.uuidInLowercaseHex()
	local assetId3 = KSIdGenerator.uuidInLowercaseHex()

	-- Create a remote preset and a remote profile

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'preset',
			_id = assetId1,
			_serverProvidedMetadata = {
				links =  {
					[ '/rels/master' ] = {
						href = "foo"
					}
				}
			},
			name = "a preset",
			importSource = {
				sha256 = '1234',
			}
		},
		':ignore:' )

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'profile',
			_id = assetId2,
			_serverProvidedMetadata = {
				links =  {
					[ '/rels/master' ] = {
						href = "bar"
					}
				}
			},
			name = "a profile",
			importSource = {
				sha256 = '5678',
			}
		},
		':ignore:' )

	-- Create a local preset which needs no saving

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'preset',
			_id = assetId3,
			name = "local preset",
			_localOnly = {
				files = {
					presetProfile = {
						path = 'some localpath',
						sha256 = '4444'
					},
				},
			},
			importSource = {
				sha256 = '4444',
			}
		},
		':ignore:' )

	local obs = rxTest:observe( indexStore:query{ sql =
			[[SELECT docId, sha256 FROM presetsProfiles where needsSave = 1 ]],
			quiesceUntilUpToDate = true
		})

	obs:expectData( {
			{
				assetId1,
				'1234',
			},
			{
				assetId2,
				'5678',
			},
		} )

	obs:dispose()

	-- Locally save the preset from remote

	rxTest:expectSingleValue( docStore:applyOverlay {
		_id = assetId1,
		_localOnly = {
			files = {
				presetProfile = {
					path = 'localpath',
					sha256 = '1234'
				},
			},
		},
	},
	':ignore:' )

	obs = rxTest:observe( indexStore:query{ sql =
		[[SELECT docId, sha256 FROM presetsProfiles where needsSave = 1 ]],
		quiesceUntilUpToDate = true
	})

	obs:expectData( {
			{
				assetId2,
				'5678',
			},
		} )

	obs:dispose()

	-- Remote updates the preset, master link not yet updated

	rxTest:expectSingleValue( docStore:applyOverlay {
		_id = assetId1,
		_serverProvidedMetadata = {
			links =  {
				[ '/rels/master' ] = {
					href = "foo",
					invalid = true,
				}
			}
		},
		importSource = {
			sha256 = '2345',
		},
	},
	':ignore:' )

	obs = rxTest:observe( indexStore:query{ sql =
		[[SELECT docId, sha256 FROM presetsProfiles where needsSave = 1 ]],
		quiesceUntilUpToDate = true
	} )

	obs:expectData( {
			{
				assetId2,
				'5678',
			},
		} )

	obs:dispose()

	-- Remote updates the preset, new master link available

	rxTest:expectSingleValue( docStore:applyOverlay {
		_id = assetId1,
		_serverProvidedMetadata = {
			links =  {
				[ '/rels/master' ] = {
					href = "new foo",
					invalid = { _delete = true },
				},
			}
		},
		importSource = {
			sha256 = 'deadbeef',
		},

	},
	':ignore:' )

	obs = rxTest:observe( indexStore:query{ sql =
		[[SELECT docId, sha256 FROM presetsProfiles where needsSave = 1 ]],
		quiesceUntilUpToDate = true
	} )

	obs:expectData( {
		{
			assetId2,
			'5678',
		},
		{
			assetId1,
			'deadbeef',
		},
	} )

end

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

-- @mark trashAssets

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

function LrmCatalogIndexDefinitionsTest.rxTestTrashAssets_FullAssetSet( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'deleted_image',
			_id = KSIdGenerator.uuidInLowercaseHex(),
			purgeDate = '2018-12-06T21:25:33.078Z',
			userCreated = '2012-01-15T11:12:15',
			userUpdated = '2012-09-14T15:22:29',
			captureDate = '2012-08-15T15:22:29',
			_serverProvidedMetadata = {
				updated = '2012-09-15T15:22:29',
				importedByUser = {
					id = 'imported by someone'
				},
			},
			_localOnly = {
				thumbnail2x = {
					md5 = 'hash',
				},
				preview = {
					md5 = 'hash',
				},
				proxy = {
					filePath = 'originals/foo_proxy.jpeg',
				},
				localUrl = 'asset-url://file.dng',
			},
			importSource = {
				originalWidth = 30,
				originalHeight = 20,
				fileName = 'File01.dng',
				importedBy = 'iPhone 10S',
				importTimestamp = '2012-01-15T11:12:15',
				hasEmbeddedDepthMap = true,
				camera = {
					name = "A camera maker",
				},
				lens = {
					name = "A lens"
				},
			},
			reviews = {
				[ KSIdGenerator.uuidInLowercaseHex() ] = {
					flag = 'pick',
				},
			},
			ratings = {
				[ KSIdGenerator.uuidInLowercaseHex() ] = {
					rating = 5,
				},
			},
			xmp = {
					dc = {
					rights = 'Copyright',
				},
				exif = {
					ExposureTime = { 100, 1 },
					FNumber = { 100, 1 },
					ApertureValue = { 100, 1 },
					FocalLength = { 100, 1 },
					ISOSpeedRatings = 100,
					FlashFired = true,
				},
				tiff = {
					Make = 'Make',
					Model = 'Model',
				},
				aux = {
					IsMergedPanorama = true,
					Lens = 'Lens',
				}
			},
			develop = {
				croppedWidth = 25,
				croppedHeight = 20,
				xmpCameraRaw = '<xmp fooEdit=0 />',
				userOrientation = 6,
				userUpdated = '2012-01-18T11:12:15'
			}
		},
		':ignore:' )

	if WFPlatformInfo.isAndroid then
	
		local obs = rxTest:observe( indexStore:query{ sql =
				[[SELECT 	
						purgeDate, thumbnailMD5, captureDate, importTimestamp, modifiedDate, 
						contentType, duration, flag, rating,
						croppedWidth, croppedHeight, fileName, width, height, 
						apertureValue, isoSpeedRatings, exposureTime, fnumber, 
						cameraMaker, cameraModel, isVideo, localUrl, isMergedHDR, hasThumbnail,
						importedByUser, syncStatus
					FROM trashAssets]],
					quiesceUntilUpToDate = true
			} )

		obs:expectData( {
			{
				'2018-12-06T21:25:33.078Z',		-- purgeDate
				'hash',							-- thumbnailmd5
				'2012-08-15T15:22:29', 			-- capture date
				'2012-01-15T11:12:15',			-- timestamp
				'2012-09-14T15:22:29',			-- modifiedDate
				1000,							-- contentType
				nil,							-- duration
				'pick',							-- flag
				5,								-- rating
				25,								-- croppedWidth
				20,								-- croppedHeight
				'File01.dng',					-- fileName
				30,								-- width
				20,								-- height
				'100.0',						-- apertureValue
				'100',							-- isoSpeedRatings
				'100',							-- exposureTime
				'100.0',						-- fnumber
				'Make',							-- cameraMaker
				'Model',						-- cameraModel
				0,								-- isVideo
				'asset-url://file.dng',			-- localUrl
				0,								-- isMergedHDR
				1,								-- hasThumbnail
				'imported by someone',			-- importedByUser
				1,
			}
		} )
		
	end

end

function LrmCatalogIndexDefinitionsTest.rxTestTrashAssets_VideoType( rxTest )

	rxTest:setTimeLimit( TEST_TIMEOUT )

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	docStore = catalog:docStore()
	indexStore = catalog:indexStore()
	
	rxTest:finally( function()
        catalog:close() 
   	end )

	rxTest:expectSingleValue( docStore:applyOverlay {
			type = 'asset',
			subtype = 'deleted_video',
			_id = KSIdGenerator.uuidInLowercaseHex(),
			_localOnly = {
				files = {
					thumbnail2x = {
						path = 'blobs/...',
					},
					preview = {
						path = 'blobs/...',
					},
					proxy = {
						path = 'originals/foo_proxy.jpeg',
					}
				}
			},
			purgeDate = '2018-12-06T21:25:33.078Z',
			video = {
			},
			importSource = {
				originalWidth = 30,
				originalHeight = 20,
				contentType = 'video/mp4',
			}
		},
		':ignore:' )
	
	local obs = rxTest:observe( indexStore:query{ sql =
			[[	
				SELECT 
					purgeDate, captureDate, importTimestamp, modifiedDate, 
					contentType, duration, flag, rating,
					croppedWidth, croppedHeight, fileName, width, height, 
					apertureValue, isoSpeedRatings, exposureTime, fnumber, 
					cameraMaker, cameraModel, isVideo, localUrl, isMergedHDR, hasThumbnail
				FROM 
					trashAssets
			]],
			quiesceUntilUpToDate = true
		} )
	
	local WFPlatformInfo = require 'WFPlatformInfo'
	if WFPlatformInfo.isiOS then

		obs:expectData(
			{
				{
					'2018-12-06T21:25:33.078Z',		-- purgeDate
					nil, 							-- capture date
					nil,							-- timestamp
					nil,							-- modifiedDate
					2001,							-- contentType
					nil,							-- duration
					'unflagged',					-- flag
					0,								-- rating
					30,								-- croppedWidth
					20,								-- croppedHeight
					nil,							-- fileName
					30,								-- width
					20,								-- height
					"",								-- apertureValue
					"",								-- isoSpeedRatings
					"",								-- exposureTime
					"",								-- fnumber
					nil,							-- cameraMaker
					nil,							-- cameraModel
					1,								-- isVideo
					nil,							-- localUrl
					0,								-- isMergedHDR
					1,								-- hasThumbnail
				}
			} )

	else

		obs:expectData( {} )
	end

end

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

return WFRxTestCase.wrapSuite( LrmCatalogIndexDefinitionsTest )

