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

WFCatSearchByImportedByUser.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2019 Adobe
All Rights Reserved.

NOTICE: All information contained herein is, and remains
the property of Adobe and its suppliers, if any. The intellectual
and technical concepts contained herein are proprietary to Adobe
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.

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

local Rx = require 'Rx'
local Observable = Rx.Observable

local KSTableUtils = require 'KSTableUtils'

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

local derefOpt = KSTableUtils.derefOpt

local isValidSearchableAssetDocument = assert( require 'WFCatIndexUtils'.isValidSearchableAssetDocument )

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

local WFCatSearchByImportedByUser = {}

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

function WFCatSearchByImportedByUser.generateIndexSchema( indexStoreSchema )

	-- table asset_importedByUser

	indexStoreSchema:addTable {

		sql = [[CREATE TABLE asset_importedByUser( importedByUser )]],
		
		relevantTypeSubtypeTuples = {
			{ 'asset', 'image' },
			{ 'asset', 'video' }
		},
		
		docValueFilter = function( docValue )
			return isValidSearchableAssetDocument( docValue )
		end,
		
		map = function( docValue, emit )

			if docValue and not docValue._deleted then

				local importedByUser = derefOpt( docValue, '_serverProvidedMetadata', 'importedByUser', 'id' ) 
				if importedByUser then
					
					emit( importedByUser )
					
				end
				
			end
		
		end,
		useLocalId = true,
		hasOneRowPerDocument = true,

	}

	indexStoreSchema:addIndex [[CREATE INDEX asset_importedByUser_index ON asset_importedByUser( importedByUser )]]
	
end

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

function WFCatSearchByImportedByUser.addSearchToSearchSchema( searchSchema )

	searchSchema:addSearchableData {
		term = 'importedByUser',
		dataType = 'fullTextSearch',
		sql = [[SELECT
					asset_importedByUser.docId
				FROM
					asset_importedByUser
				WHERE
					asset_importedByUser.importedByUser == ?
		]],
		query_params = 'userId',
	}

	searchSchema:addSearchableData {
		term = 'importedByMyself',
		dataType = 'none',
		sql = [[SELECT
					assets.docId
				FROM
					assets
				WHERE
					importedByUser IS NULL
		]],
	}
end

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

local function combineWithMyself( usersObservable, myselfObservable )
	
	return Observable.combineLatest( function( users, maybeMyself )
		
		if maybeMyself then
			local ret = { 'kMyself' }
			KSTableUtils.appendArray( ret, users )
			return ret
		end
		
		return users
		
	end, usersObservable, myselfObservable )
	
end

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

function WFCatSearchByImportedByUser.collectImportedByUserOfRequiredAssets( wfCatalog, assetLocalIds )
	
	local otherUsersObservable = wfCatalog:indexStore():query {
		sql = [[SELECT DISTINCT asset_importedByUser.importedByUser, feedback_user.fullName
					FROM asset_importedByUser
					INNER JOIN feedback_user ON ( asset_importedByUser.importedByUser == feedback_user.userId )
					INNER JOIN CARRAY( ?, ?, 'int32' ) AS assetLocalIds ON assetLocalIds.value == asset_importedByUser.docId
					ORDER BY importedByUser COLLATE i18n_collate ASC]],
		calm = 5,
		assetLocalIds,
		#assetLocalIds
	}
		:map( function( rows )
			local ret = {}
			
			for _, row in ipairs( rows ) do
				ret[ #ret + 1 ] = {
					userId = row[ 1 ],
					fullName = row[ 2 ],
				}
			end
			
			return ret
		end )
		
	local myselfObservable = wfCatalog:indexStore():query {
		sql = [[SELECT assetLocalIds.value
					FROM CARRAY( ?, ?, 'int32' ) AS assetLocalIds
					LEFT JOIN asset_importedByUser ON asset_importedByUser.docId == assetLocalIds.value
					WHERE asset_importedByUser.docId IS NULL
					LIMIT 1
			]],
		calm = 5,
		assetLocalIds,
		#assetLocalIds
	}
		:map( function( rows )
			if rows and #rows > 0 then
				return true
			end
			
			return false
		end )

	
	return combineWithMyself( otherUsersObservable, myselfObservable )
	
end

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

function WFCatSearchByImportedByUser.collectImportedByUserOfAllAssets( wfCatalog )
	
	local otherUsersObservable = wfCatalog:indexStore():query {
		sql = [[SELECT DISTINCT asset_importedByUser.importedByUser, feedback_user.fullName
					FROM asset_importedByUser
					INNER JOIN feedback_user ON ( asset_importedByUser.importedByUser == feedback_user.userId )
					WHERE feedback_user.spaceId IS NULL
					ORDER BY importedByUser COLLATE i18n_collate ASC]],
		calm = 5,
	}
		:map( function( rows )
			local ret = {}
			
			for _, row in ipairs( rows ) do
				ret[ #ret + 1 ] = {
					userId = row[ 1 ],
					fullName = row[ 2 ],
				}
			end
			
			return ret
		end )
		
	local myselfObservable = wfCatalog:indexStore():query {
		sql = [[SELECT CASE
				WHEN 
					( SELECT COUNT( docId ) from assets ) > ( SELECT COUNT( docId ) from asset_importedByUser )
				THEN
					1
				ELSE
					0
				END
		]],
		calm = 5,
	}
		:map( function( rows )
			return derefOpt( rows, 1, 1 ) == 1
		end )
	
	return combineWithMyself( otherUsersObservable, myselfObservable )
	
end

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

return WFCatSearchByImportedByUser
