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

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

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

local LrmCatalogTestHelper = {}

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

	-- RxLua
local Rx = require 'Rx'

	-- WF.core.reactive
local KSPromises = require 'KSPromises'

	-- WF.core.utils
local KSIdGenerator = require 'KSIdGenerator'

	-- WF.core.os
local KSPathUtils = require 'KSPathUtils'
local WFFileUtils = require 'WFFileUtils'

	-- WF.oz_client.sync_agent
local WFOzSyncConstants = require 'WFOzSyncConstants'
local OzCatalogUrls = require 'OzCatalogUrls'

	-- WF.oz_client.managed_catalog
local WFCatMockCatalog = require 'WFCatMockCatalog'
local WFCatUser = require 'WFCatUser'
local WFCatSpec = require 'WFCatSpec'
local WFCatalog = require 'WFCatalog'
local OzCatalogServiceViaWFCatalog = require 'OzCatalogServiceViaWFCatalog'
local runUntilDone = require 'WFRxRunUntilDone'

	-- WF.sqlite.doc_store
local WFRxDocStore = require 'WFRxDocStore'
local OzDocStoreViaWFRxDocStore = require 'OzDocStoreViaWFRxDocStore'

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

	-- WF.lrmobile
local LrmSyncClient = require 'LrmSyncClient'

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

local catalogIndexDefinitions = 'LrmCatalogIndexDefinitions.lua'

function LrmCatalogTestHelper.makeDatabases( docStorePath )

	docStorePath = docStorePath or ':memory:' .. tostring( KSIdGenerator.localCounter() )
	local rxDocStore = WFRxDocStore( docStorePath )
	local ozDocStore = OzDocStoreViaWFRxDocStore( rxDocStore )
	
	local function dataCache( this )
	
		assert( false, 'No longer used' )
		
	end
	
	rawset( ozDocStore, 'dataCache', dataCache )
	
	local indexStore = WFRxIndexStore( rxDocStore, catalogIndexDefinitions )
	return ozDocStore, indexStore, rxDocStore
								
end

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

function LrmCatalogTestHelper.makeInMemoryDatabases()

	return LrmCatalogTestHelper.makeDatabases()
	
end

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

function LrmCatalogTestHelper.makeCatalogService( rxTest, docStorePath )
	
	local wfCatalog, catalogId, userId = LrmCatalogTestHelper.makeWFCatalog( rxTest, docStorePath )
	
	local user = wfCatalog:ozUser()
	local dataCache = nil
	
	local Cl = {
		OzCatalogServiceViaWFCatalog,
		
		getDataCache = function( self )
		
			return self:OzCatalogService_getDataCache()
				:tap( function( localDataCache )
				
					dataCache = localDataCache
					
				end )
			
		end,
		
		getDataCachePath = function( self )
		
			local fileRootPath = wfCatalog:fileSpec():rootPath()
			
			WFFileUtils.mkdir( fileRootPath )
			
			local cachePath = KSPathUtils.child( fileRootPath, "previewCache" )
			
			return Rx.Observable.just( cachePath )
			
		end,
		
		test_getWFCatalog = function( self )
		
			return wfCatalog
			
		end,
	}
	local ClClass = Rx.Class( 'OzCatalogService', Cl )
	local catalogService = ClClass( Rx.Observable.just( wfCatalog ) )
	
	local syncClient = LrmSyncClient( wfCatalog, catalogIndexDefinitions, nil, nil, dataCache )
	catalogService:setSyncClient( syncClient )
	
	local userIdP = KSPromises.resolvedPromiseP( 'data', userId )
	local freemiumUserIdP = KSPromises.resolvedPromiseP( 'data', WFOzSyncConstants.kGlobalDocumentId )
	
	rawset( catalogService, 'private:userIdP', userIdP )
	rawset( catalogService, 'private:freemiumUserIdP', freemiumUserIdP )
	rawset( catalogService, '_isAuthenticated', true )
	rawset( catalogService, '_catalogId', catalogId )
	
	rawset( catalogService, 'ozUserIdP', function( _, badParam )
	
		assert( badParam == nil, 'No args expected' )
		
		if rawget( catalogService, '_isAuthenticated' ) then
			return rawget( catalogService, 'private:userIdP' )
		else
			return rawget( catalogService, 'private:freemiumUserIdP' )
		end
		
	end )
	
	rawset( catalogService, 'setUserIsAuthenticated', function( _, isAuthenticated )
		
		assert( type( isAuthenticated ) == 'boolean', 'Boolean arg expected' )
		
		rawset( catalogService, '_isAuthenticated', isAuthenticated )
		
	end )
	
	rawset( catalogService, 'close', function()
	
		-- If rxTest, wfCatalog is set to close by WFCatMockCatalog with rxTest:finally
		
		if dataCache then
			dataCache:haltAndDelete()
				:tapOnCompleted( function()
					syncClient:close()
					
					if not rxTest then
						wfCatalog:close()
						user:close()
					end
				end )
			:call( runUntilDone )
		
		else
			syncClient:close()
			
			if not rxTest then
				wfCatalog:close()
				user:close()
			end
		end
		
	end )

	rawset( catalogService, 'ozCatalogSpec', function()
		return nil -- stubbed out for now
	end )

	return catalogService, wfCatalog, catalogId, userId
	
end

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

function LrmCatalogTestHelper.makeWFCatalog( rxTest, docStorePath )

	local wfCatalog, catalogId, userId
	local indexSpecScript = catalogIndexDefinitions
	
	if rxTest then
		
		local catalogOptions = {
			indexDefinitions = indexSpecScript
		}
		
		wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, docStorePath, nil, catalogOptions )
	
		userId = wfCatalog:ozUserId()
		catalogId = wfCatalog:ozCatalogId()
		
	else
	
		docStorePath = docStorePath or ':memory:' .. tostring( KSIdGenerator.localCounter() )
		local userInfoCachePath = ':memory:'
		
		userId = KSIdGenerator.uuidInLowercaseHex()
		catalogId = KSIdGenerator.uuidInLowercaseHex()
		
		local serverBaseUrl = OzCatalogUrls.baseServerUrl
		local rootCatalogPath = KSPathUtils.child( KSPathUtils.getStandardFilePath( 'temp' ), KSIdGenerator.uuidInLowercaseHex() )

		local user = WFCatUser( serverBaseUrl, userId, userInfoCachePath )
		local catSpec = WFCatSpec( user, catalogId )
		
		local catalogOptions = {
			indexSpecScript = indexSpecScript,
			setupConflictResolver = false,
			docStorePath = docStorePath
		}

		wfCatalog = WFCatalog( catSpec, rootCatalogPath, catalogOptions )

	end

	return wfCatalog, catalogId, userId
	
end

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

function LrmCatalogTestHelper.equalToSourceTable( docValue, sourceTable )

	local function makeDeepCompare( source, target  )
					
		for k, v in pairs( source ) do
	
			if type( v ) == 'table' and target[ k ] then
				makeDeepCompare( v, target[ k ] )
			
			else
			
				if not target[ k ] then
				
					source[ k ] = nil
					
				end
				
			end
			
		end
	
	end
	
	makeDeepCompare( docValue, sourceTable )
	
	return docValue
					
end

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

function LrmCatalogTestHelper.makeTestFilePath()

	local path = KSPathUtils.getStandardFilePath( "temp" )
	path = KSPathUtils.child( path, KSIdGenerator.uuidInLowercaseHex() )
	
	return path
	
end

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

return LrmCatalogTestHelper
