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

WFCatSearchByAlbum.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.

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

local KSTableUtils = require 'KSTableUtils'
local KSStringUtils = require 'KSStringUtils'
local WFLogger = require 'WFLogger'
local WFCatSyncStatus = require 'WFCatSyncStatus'
local LrClassicSyncStatus = require 'LrClassicSyncStatus'

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

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

local logger = WFLogger( 'WFCatSearchByAlbum' )

local KSTableUtils_derefOpt = assert( KSTableUtils.derefOpt )

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

local WFCatSearchByAlbum = {}

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

--[[
	Index definitions for finding assets in albums.  This includes the SQLite index.
	Index definitions for identifying what asset are in albums.
--]]

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

function WFCatSearchByAlbum.generateIndexSchema( indexStoreSchema )

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

	indexStoreSchema:addTable {

		sql = [[CREATE TABLE album_asset_v2( assetId, albumId, sortOrder )]],

		useLocalId = true,
		
		hasOneRowPerDocument = true,
		
		relevantTypeSubtypeTuples = {
			{ 'album_asset', 'NULL' },
		},
		
		map = function( docValue, emit )

			if docValue and not docValue._deleted then
				if docValue._docType == 'album_asset' or docValue.type == 'album_asset' then

					local albumId = docValue.album and docValue.album.id
					local assetId = docValue.asset and docValue.asset.id
					local updateTimestamp = docValue.updated
					local sortOrder = docValue.order

					if not updateTimestamp then
						updateTimestamp = KSTableUtils_derefOpt( docValue, '_serverProvidedMetadata',
																	'updated' )
					end

					if albumId and assetId then
						emit( assetId, albumId, sortOrder )
					end

				end

			end

		end,

	}

	indexStoreSchema:addIndex
		[[CREATE INDEX album_asset_v2_index ON album_asset_v2( albumId, sortOrder, assetId )]]
	
	indexStoreSchema:addIndex
		[[CREATE INDEX album_asset_v2_assetId ON album_asset_v2( assetId )]]
		
	indexStoreSchema:addIndex
		[[CREATE INDEX album_asset_v2_albumId ON album_asset_v2( albumId )]]
		
	indexStoreSchema:addIndex
		[[CREATE INDEX album_asset_v2_assetIdalbumId ON album_asset_v2( assetId, albumId )]]
		
	indexStoreSchema:addIndex
		[[CREATE INDEX album_asset_v2_hotmess ON album_asset_v2( albumId, assetId )]]
		
	--------------------------------------------------------------------------------

	indexStoreSchema:addTable {
			
		sql = [[CREATE TABLE albums( 
					albumId,
					spaceId,
					name, 
					nameLC, 
					updateTimestamp, 
					createdTimestamp, 
					parentId, 
					coverId, 
					sortOrder, 
					subtype, 
					hidden BOOLEAN DEFAULT 0,
					isMarkedForOffline,
					assetSortOrder,
					hasDisplayFilters,
					title,
					syncStatus)]],

		useLocalId = true,
		
		hasOneRowPerDocument = true,
		
		relevantTypeSubtypeTuples = {
			{ 'album', 'collection' },
			{ 'album', 'collection_set' }
		},
		
		map = function( docValue, emit )

			-- Don't emit index store records for album subtypes we don't understand since the UI may not show
			-- things correctly. The basic album subtype is of type 'collection' which is the classic type of album. 
			-- The full list of subtypes can be found here http://apidocs.adbecrsl.com/v2/data-model/album/index.html
			-- Since the different subtypes tend to represent different concepts they may end up in separate tables
			-- entirely.
			if docValue and docValue.type == 'album' 
					and ( docValue.subtype == 'collection' or docValue.subtype == 'collection_set' ) 
					and not docValue._deleted then

				local name = docValue.name
				
				local albumId = docValue._id
				local spaceId = docValue._spaceId
				local parentId = KSTableUtils_derefOpt( docValue, 'parent', 'id' )
				local updateTimestamp = KSTableUtils_derefOpt( docValue, 'userUpdated' )
				local createdTimestamp = KSTableUtils_derefOpt( docValue, 'userCreated' )
				local coverId = KSTableUtils_derefOpt( docValue, 'cover', 'id' )
				local order = docValue.order
				local subtype = docValue.subtype
				local hidden = docValue.hideInOrganize and 1 or 0
				
				local isMarkedForOffline = WFCatFileSpec.getMarkedForOfflineUseFromDocValue( docValue ) and 1 or 0
				
				local assetSortOrder = KSTableUtils_derefOpt( docValue, 'assetSortOrder' )
				
				if spaceId then
				
					-- For space-feed documents, the asset sort order can be changed by the contributor/viewer
					-- but it is a local-only change; they cannot overwrite the album order set by the album owner.
		
					assetSortOrder = KSTableUtils_derefOpt( docValue, '_localOnly', 'universal', 'assetSortOrder' ) or assetSortOrder
					
				end
				
				local ratingAtLeast = KSTableUtils_derefOpt( docValue, 'presentation', 'filters', 'ratingAtLeast' )
				ratingAtLeast = tonumber( ratingAtLeast ) or 0
				
				local pickedOnly = KSTableUtils_derefOpt( docValue, 'presentation', 'filters', 'pickedOnly' ) or false
				
				local hasDisplayFilters = ratingAtLeast > 0 or pickedOnly
				hasDisplayFilters = hasDisplayFilters and 1 or 0
				
				local title = KSTableUtils_derefOpt( docValue, 'story', 'title' )
				
				local syncStatus 
				
				if WFPlatformInfo.isClassic() then
				
					syncStatus = LrClassicSyncStatus.getAlbumSyncStatus( docValue )
					
				else
				
					syncStatus = WFCatSyncStatus.getAlbumSyncStatus( docValue )
				
				end
				if albumId and name then
				
					logger:infof( 'Emitting album. Id: %s', albumId )
					
					emit( albumId, spaceId, name, KSStringUtils.lower( name ), updateTimestamp, createdTimestamp, 
							parentId, coverId, order, subtype, hidden, isMarkedForOffline, assetSortOrder,
							hasDisplayFilters, title, syncStatus )
							
				end

			end

		end,
	}
	
	indexStoreSchema:addIndex
		[[CREATE INDEX albums_albumIddocId ON albums( albumId, docId )]]
	indexStoreSchema:addIndex
		[[CREATE INDEX albums_name ON albums( nameLC )]]
	indexStoreSchema:addIndex
		[[CREATE INDEX albums_parent_id ON albums( parentId )]]
	indexStoreSchema:addIndex
		[[CREATE INDEX albums_subtype ON albums( subtype )]]
	indexStoreSchema:addIndex
		[[CREATE INDEX albums_isMarkedForOffline ON albums( isMarkedForOffline, albumId )]]
	indexStoreSchema:addIndex
		[[CREATE INDEX albums_syncStatus ON albums( albumId, syncStatus )]]
end

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

function WFCatSearchByAlbum.addSearchToSearchSchema( searchSchema )

	searchSchema:addSearchableData {
		dataType = 'albumAssets',
		sql = 
			[[SELECT assets.docId 
			  FROM albums, album_asset_v2, assets 
			  WHERE albums.docId = ? AND
			  			albums.albumId == album_asset_v2.albumId AND
			  			album_asset_v2.assetId == assets.assetId
			  ORDER BY assets.docId]],
		term = 'album',
	}
	
	searchSchema:addSearchableData {
		dataType = 'projectAlbumAssets',
		sql = 
			[[SELECT assets.docId 
			  FROM project_albums, album_asset_v2, assets 
			  WHERE project_albums.docId = ? AND
			  			project_albums.albumId == album_asset_v2.albumId AND
			  			album_asset_v2.assetId == assets.assetId
			  ORDER BY assets.docId]],
		term = 'project_album',
	}

	searchSchema:addSearchableData {
		dataType = 'fullTextSearch',
		sql = [[SELECT assets.docId
					FROM assets
					WHERE assets.subtype IN ( 'image', 'video' )
						AND assets.assetId NOT IN ( 
							SELECT DISTINCT album_asset_v2.assetId
							FROM album_asset_v2
							INNER JOIN albums ON albums.albumId == album_asset_v2.albumId
						)
					ORDER BY assets.docId]],
		term = 'no-album',
	}
	
end

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

return WFCatSearchByAlbum
