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

WFCatIndexDefinitions.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2015 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.utils
local KSTableUtils = require 'KSTableUtils'
local KSStringUtils = require 'KSStringUtils'

	-- WF.oz_client.managed_catalog
local WFCatIndexUtils = require 'WFCatIndexUtils'
local WFCatFileSpec = require 'WFCatFileSpec'

	-- WF.sqlite.index_store
local WFRxIndexStoreSchema = require 'WFRxIndexStoreSchema'

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

local derefOpt = KSTableUtils.derefOpt
local isValidDisplayableAssetDocument = WFCatIndexUtils.isValidDisplayableAssetDocument
local getDuration = assert( WFCatIndexUtils.getDuration )
local getOrientationWidthAndHeight = assert( WFCatIndexUtils.getOrientationWidthAndHeight )

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

local function getRating( docValue )

	local ratings = derefOpt( docValue, 'ratings' )
	
	if ratings then

		-- Due to legacy issues, ratings are keyed by user id. We can now assume
		-- only one user (the current user) is able to rate a photo.

		local _, v = next( ratings )

		if v then
			return v.rating or 0
		end
	end
	
	return 0
end

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

local flagNameToInteger = {
	reject = -1,
	unflagged = 0,
	pick = 1,
}

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

local function getFlag( docValue )

	local reviews = derefOpt( docValue, 'reviews' )
	
	if reviews then

		-- Due to legacy issues, flags are keyed by user id. We can now assume
		-- only one user (the current user) is able to flag a photo.

		local _, v = next( reviews )

		if v then
			local flagName = v.flag
			
			if flagName then
				return flagNameToInteger[ flagName ] or 0
			end

		end
	end
	
	return 0
end

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

local WFCatIndexDefinitions = {}

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

local tableDefinitions = {}
local indexDefinitions = {}

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

tableDefinitions.assets = {

	sql = [[CREATE TABLE assets( 
				width INTEGER, 
				height INTEGER, 
				orientation INTEGER, 
				captureDate, 
				filename, 
				filenameLC, 
				assetId, 
				subtype, 
				rating INTEGER, 
				flag INTEGER, 
				duration INTEGER, 
				isMedia,
				isMarkedForOffline,
				spaceId,
				importedByUser,
				serverCreated )]],
	
	relevantTypeSubtypeTuples = {
		{ 'asset', 'image' },
		{ 'asset', 'video' },
		{ 'asset', 'stack' },
	},
	
	map = function( docValue, emit )
		
		local isDisplayable, displayableDocValue = isValidDisplayableAssetDocument( docValue )
		
		if isDisplayable then

			local subtype = docValue.subtype
		
			local isMedia = subtype == 'image' or subtype == 'video'

			local orientation, width, height = getOrientationWidthAndHeight( displayableDocValue )

			local filename = derefOpt( displayableDocValue, 'importSource', 'fileName' )
			
			local filenameLC = ""
			
			if filename and type( filename ) == "string" then
			
				filenameLC = KSStringUtils.lower( filename )
				filenameLC = KSStringUtils.trim( filenameLC )
				
			end
			
			local captureDate = derefOpt( displayableDocValue, 'captureDate' )

			local rating = getRating( displayableDocValue )

			local flag = getFlag( displayableDocValue )

			local duration = getDuration( displayableDocValue )

			isMedia = isMedia and 1 or 0

			local isMarkedForOffline = WFCatFileSpec.getMarkedForOfflineUseFromDocValue( docValue ) and 1 or 0
			
			local spaceId = docValue._spaceId
			
			local importedByUser = derefOpt( docValue, '_serverProvidedMetadata', 'importedByUser', 'id' ) 
			
			local serverCreated = derefOpt( docValue, '_serverProvidedMetadata', 'created' )
			
			if width and height and captureDate then

				emit( width, height, orientation, captureDate, filename, filenameLC, docValue._id, 
						subtype, rating, flag, duration, isMedia, isMarkedForOffline, spaceId, 
						importedByUser, serverCreated )

			end

		end

	end,

	useLocalId = true,
	hasOneRowPerDocument = true,

}

indexDefinitions.assets_assetIddocId =
	[[CREATE INDEX assets_assetIddocId ON assets( assetId, docId )]]
indexDefinitions.assets_assetIdsubtype = 
	[[CREATE INDEX assets_assetIdsubtype ON assets( assetId, subtype )]]
indexDefinitions.assets_subtype = 
	[[CREATE INDEX assets_subtype ON assets( subtype )]]
indexDefinitions.assets_captureDatefilename =
	[[CREATE INDEX assets_captureDatefilename ON assets( captureDate, filenameLC COLLATE i18n_collate )]]
indexDefinitions.assets_assetIdIsMediaCaptureDateFilenameLCServerCreated =
	[[CREATE INDEX assets_assetIdIsMediaCaptureDateFileNameLCServerCreated ON assets( assetId, isMedia, captureDate, fileNameLC, serverCreated )]]
indexDefinitions.assets_isMarkedForOffline =
	[[CREATE INDEX assets_isMarkedForOffline ON assets( isMarkedForOffline, assetId )]]

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

local sqlitePageSize = 4096

local indexStoreSchema = WFRxIndexStoreSchema( sqlitePageSize )

indexStoreSchema:addDatabaseInitRoutine( require 'WFSQLiteSetLogicImp'.registerSetModule )

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

for _, definition in pairs( tableDefinitions ) do
	indexStoreSchema:addTable( definition )
end

for _, definition in pairs( indexDefinitions ) do
	indexStoreSchema:addIndex( definition )
end


local function getIndexSchemaGenerators(  )
	return { 
		'NmbAlbums',
		'NmbSimpleDocStoreUpdater',
		'NmbPresetDocumentProcessor',
		'NmbPathRestorer',
		'NmbFileMover',
		'NmbExternalDevelopSettings',
		'WFCatBinaryUploader',
		'WFCatConflictResolver',
		'WFCatCollaboration',
		'WFCatCollaborator',
		'LrFavoritesIndexDefinitions',
		'LrCommentsIndexDefinitions',
		'NmbDCPDocumentProcessor',
		'WFCatDelete',
		'WFCatErrorHandler',
		'WFCatIdleDownloader',
		'WFCatImportDuplicateFiles',
		'WFCatSearchHandler',
		'WFCatSortHandler',
		'WFCatStacks',
		'WFCatStaleBinaryRemover',
		'WFCatStorage',
		'WFCatSyncStatus',
		'WFCatPerson',
		'WFCatFaces',
		'WFCatVersions',
		'LrWatermarkIndexDefinitions',
		'NmbCameraModelUsageIndexDefinition',
		}
end


--------------------------------------------------------------------------------
local function generateIndexSchema( theIndexStoreSchema )

	local indexSchemaGenerators = getIndexSchemaGenerators()
	
	for _, generator in pairs( indexSchemaGenerators ) do
		require ( generator ).generateIndexSchema( theIndexStoreSchema )
	end
	
end

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

generateIndexSchema ( indexStoreSchema )

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

local WFConfiguration = require 'WFConfiguration'

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

if WFConfiguration.Nimbus.Nmb5582InvalidOriginals then

	require 'WFCatInvalidOriginalHandler'.generateIndexSchema( indexStoreSchema )

end

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

if WFConfiguration.Shared.enableDashboard then

	require 'NmbCatalogDashboard'.generateIndexSchema( indexStoreSchema )

end

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

WFCatIndexDefinitions.indexStoreSchema = indexStoreSchema

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

return WFCatIndexDefinitions
