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

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

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

	-- RxLua
local Rx = require 'Rx'

	-- WF.core.utils
local WFCloseSupport = require 'WFCloseSupport'
local WFArguments = require 'WFArguments'
local WFLogger = require 'WFLogger'

	-- WF.oz_client.managed_catalog
local WFCatIdleDownloader = require 'WFCatIdleDownloader'
local WFCatSyncClientBase = require 'WFCatSyncClientBase'

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

local check = assert( WFArguments.check )

local logger = WFLogger( 'WFCatSyncClientImp' )

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

-- @mark WFCatSyncClientImp namespace

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

local syncClientImpMethods = {

	_syncClientBase = false,
		-- (WFCatSyncClientBase)
		
	WFCloseSupport.addCloseSupportMethods,
	
}

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

local function albumAssetsForFilteredAssetsQueryFn( catalog, assetIds )
	
	return catalog:indexStore():queryOnce {
				sql = [[SELECT album_asset_v2.docId, album_asset_v2.assetId FROM CARRAY( ?, ?, 'char*' ) AS ai JOIN album_asset_v2 ON 
							ai.value = album_asset_v2.assetId]],
				assetIds,
				#assetIds,
			}
end

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

function syncClientImpMethods:__init( options )

	check( 'WFCatSyncClientImp', 'table' )
	
	options.albumAssetsForFilteredAssetsQueryFn = albumAssetsForFilteredAssetsQueryFn
	
	local syncClientBase = WFCatSyncClientBase( options )
	
	self:setOwned {
		_syncClientBase = syncClientBase
	}
	
	-- Setup custom asset sync handlers
	
	local catalogPuller = syncClientBase:getCatalogPuller()
	
	catalogPuller:addAssetTypeHandler( 'asset', WFCatIdleDownloader.addWaitingForProxyAnnotation )
	
end

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

function syncClientImpMethods:__index( k )

	-- When code attempts to call an undefined method on a WFCatSyncClientImp object,
	-- this function is called instead. If the below code determines that the
	-- WFCatSyncClientBase class has such a method, then that method is called. With
	-- this, all the class methods defined within WFCatSyncClientBase are automatically
	-- exposed as class methods of WFCatSyncClientImp.

	-- Any sync method that requires special handling, or otherwise must perform additional
	-- work beyond calling the WFCatSyncClientBase method directly must be defined manually.
	-- All manually-defined methods take precedent over the metamethod mappings below.

	if not k then
		return
	end

	if self._syncClientBase:hasMethod( k ) then
	
		local syncClientBaseFn = function( _, ... )
		
			logger:infof( "Now calling WFCatSyncClientBase:%s via WFCatSyncClientImp", k )
		
			return self._syncClientBase[ k ]( self._syncClientBase, ... )

		end
		
		return syncClientBaseFn

	else
	
		local errorFn = function( _, ... )
		
			local warning = string.format( "Unable to call unknown method: %s", k  )
	
			logger:warn( warning )
		
			return Rx.Observable.throw( warning )

		end
	
		return errorFn
	
	end

end

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

function syncClientImpMethods:getSyncClientBaseMethodList()

	check( 'WFCatSyncClientImp' )

	-- This function returns a list of methods on the WFCatSyncClientBase object.
	-- It is used to build up the message handlers within WFCatSyncClientMessageProcessor.

	return self._syncClientBase.listMethods()

end

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

function syncClientImpMethods:_DEBUG_SyncClientReturnsFoo()

	check( 'WFCatSyncClientImp' )
	
	return Rx.Observable.just( 'foo' )

end

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

function syncClientImpMethods:close()

	check( 'WFCatSyncClientImp' )

end

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

return Rx.Class( 'WFCatSyncClientImp', syncClientImpMethods )
