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

WFCatSortHandler.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 WFCatSortHandler = {}
local _isInitialized = false

local HandlerType = {
  indexStoreSchema = 'indexStoreSchema',
  sortSchema = 'sortSchema',
}

WFCatSortHandler.Default_SortOrder = "DESC"
WFCatSortHandler.Default_SortType = "date"
WFCatSortHandler.valid_SortOrders = 
	{ 
		ASC = true,
		DESC = true,
	}


local internatData = {}
--------------------------------------------------------------------------

function WFCatSortHandler.registerSortProviders()

	if _isInitialized == false then
	
		local WFCatSortProviderList = require 'WFCatSortProviderList'
		
		-- Some  providers support both search and sort data.
		-- So when they were added to WFCatSearchProviderList the indexStoreSchema would have been added .
		-- Based on the capacity of the provider, the provider type can be added
		

		-- WFCatSortByAssetID is a special purpose sort used only for import
		-- sort by AssetId works, but isn't necessarily valueable to a user. keep for debugging
		--		WFCatSortProviderList.registerSortProvider( 'WFCatSortByAssetId', 'assetId',
		--			{ HandlerType.sortSchema } )

		WFCatSortProviderList.registerSortProvider( 'WFCatSortByRating', 'rating',
			{ HandlerType.sortSchema } )

		WFCatSortProviderList.registerSortProvider( 'WFCatSortByModifiedTime', 'modifiedTime',
			{ HandlerType.indexStoreSchema, HandlerType.sortSchema } )	
		
		WFCatSortProviderList.registerSortProvider( 'WFCatSortByFileName', 'fileName',
			{ HandlerType.sortSchema } )	
		
		--WFCatSearchByImportTime adds the schema
		WFCatSortProviderList.registerSortProvider( 'WFCatSortByImportTime', 'importTime',
			{ HandlerType.sortSchema } )	
		
		WFCatSortProviderList.registerSortProvider( 'WFCatSortByCustomOrder', 'custom',
			{ HandlerType.sortSchema } )

		-- WFCatOnlineSearchResultTable adds the index store schema
		WFCatSortProviderList.registerSortProvider( 'WFCatSortByOnlineRelevance', 'onlineRelevancy',
			{ HandlerType.sortSchema } )
			
		WFCatSortProviderList.registerSortProvider( 'WFCatSortByRecentlyEdited', 'recentlyEdited',
			{ HandlerType.sortSchema } )	
		
		_isInitialized = true

	end
	
end

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

function WFCatSortHandler.executeSort( wfCatalog, assetIds )

	if internatData._sortHandlerDetails then 
	
		local sortProvider = internatData._sortHandlerDetails.handler
		
		if sortProvider then 
			return sortProvider.executeSort( wfCatalog, assetIds, internatData._sortHandlerDetails.order, internatData._sortHandlerDetails.sortFieldInfo )
		end
		
	end
	
	return require 'Rx'.Observable.just( nil )
end

--------------------------------------------------------------------------------
function WFCatSortHandler.getRegisteredSortHandlers( handlerType )
	return  require 'WFCatSortProviderList'.getProviderList( handlerType )
end

--------------------------------------------------------------------------------
function WFCatSortHandler.generateIndexSchema( indexStoreSchema )

	WFCatSortHandler.registerSortProviders()
	
	local indexStoreSchemeProviders = WFCatSortHandler.getRegisteredSortHandlers(
		HandlerType.indexStoreSchema )
		
	for  _, indexStoreSchemeProvider in pairs( indexStoreSchemeProviders ) do	
		local provider = require ( indexStoreSchemeProvider )
		provider.generateIndexSchema( indexStoreSchema )		
	end
	
end

--------------------------------------------------------------------------
local function getRegisteredSortHandler( sortTerm ) 
	WFCatSortHandler.registerSortProviders()
	if sortTerm ~= nil then
		local sortProviders = WFCatSortHandler.getRegisteredSortHandlers( HandlerType.sortSchema )
		local sortProvider = sortProviders[ sortTerm ]
		if sortProvider ~= nil then
			return require ( sortProvider )
		end
	end
	
	return nil
	
end

--------------------------------------------------------------------------
local function validateSortDetails( info )
	if info and  info.handler then
		if info.handler.isSortingNeeded == nil or info.handler.isSortingNeeded( info ) then
			info.order = WFCatSortHandler.getValidatedSortOrder( info.order )
			return true
		end
	end
	
	return false
	
end

--------------------------------------------------------------------------
function WFCatSortHandler.getValidatedSortOrder( currentRequestedSortOrder )
	-- ensuring not to pass any invalid argument as the sort order	
	return WFCatSortHandler.valid_SortOrders [ currentRequestedSortOrder ] 
			and currentRequestedSortOrder or WFCatSortHandler.Default_SortOrder

end

--------------------------------------------------------------------------
function  WFCatSortHandler.initSortHandlerDetails ( sortDescription )
	
	local isInfoDefauult = false
	internatData._sortHandlerDetails = nil
	-- If the sort type is the default, we dont need to do any special sorting
	-- as the default sort is handled in the search operation itself.
	-- this is handled by not registering a sort hadnled for the default sort type
	-- so if the type is 'date' handler will be nil
	if sortDescription ~= nil then
		if isInfoDefauult == false then
			local handler = getRegisteredSortHandler( sortDescription.handlerType )
			if handler ~= nil then
				internatData._sortHandlerDetails = {}
				internatData._sortHandlerDetails[ 'handler' ] = handler
				internatData._sortHandlerDetails[ 'order' ] = sortDescription.sortOrder
				internatData._sortHandlerDetails[ 'sortFieldInfo' ] = sortDescription.sortFieldInfo
				if validateSortDetails(internatData._sortHandlerDetails) == false then
					internatData._sortHandlerDetails = nil
				end
			end
		end
	end
	
end

--------------------------------------------------------------------------------
function WFCatSortHandler.isMultipleDataExpectedFromAsset()
	local handler =  WFCatSortHandler.getSortHandler()
	return handler and handler.isMultipleDataExpectedFromAsset and handler.isMultipleDataExpectedFromAsset() or false
end

--------------------------------------------------------------------------------
function WFCatSortHandler.getAdditionalDataForAsset( resultObj )
	local handler =  WFCatSortHandler.getSortHandler()
	return handler and handler.getAdditionalDataForAsset and handler.getAdditionalDataForAsset( resultObj ) or false
end

--------------------------------------------------------------------------------
function WFCatSortHandler.getAssetIdPos( resultObj )
	local handler =  WFCatSortHandler.getSortHandler()
	return handler and handler.getAssetIdPos and handler.getAssetIdPos( resultObj ) or 1
end

--------------------------------------------------------------------------
function WFCatSortHandler.getSortOrder( sortInfo )
	if internatData._sortHandlerDetails ~= nil then
		return internatData._sortHandlerDetails.order
	else
		return WFCatSortHandler.Default_SortOrder 
	end
end

--------------------------------------------------------------------------
function WFCatSortHandler.getSortHandler(  )
	if internatData._sortHandlerDetails ~= nil then
		return internatData._sortHandlerDetails.handler
	else
		return nil
	end
end

--------------------------------------------------------------------------------
function WFCatSortHandler.isSortingNeeded( )
	if internatData._sortHandlerDetails ~= nil then
		return true
	end
	return false
end
--==============================================================================

return WFCatSortHandler
