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

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 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:'
	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( mixin, docStorePath )

	assert( type( mixin ) == 'nil', 'No mixin support' )
	
	docStorePath = docStorePath or ':memory:'
	local userInfoCachePath = ':memory:'
	local userId = KSIdGenerator.uuidInLowercaseHex()
	local serverBaseUrl = OzCatalogUrls.baseServerUrl
	local catalogId = KSIdGenerator.uuidInLowercaseHex()
	local rootCatalogPath = KSPathUtils.getStandardFilePath 'temp'
	local indexSpecScript = catalogIndexDefinitions
	
	local catalogOptions = {
		indexSpecScript = indexSpecScript,
		setupConflictResolver = false,
		docStorePath = docStorePath,
		noFileAccessDb = true,
--		docStorePath = KSPathUtils.child( rootCatalogPath, KSIdGenerator.uuidInLowercaseHex() )
	}
	
	debug.print( '------------ %s', catalogId )
	local user = WFCatUser( serverBaseUrl, userId, userInfoCachePath )
	
	local catSpec = WFCatSpec( user, catalogId )
	local catalog = WFCatalog( catSpec, rootCatalogPath, catalogOptions )
	
	local dataCache = nil
	
	local Cl = {
		OzCatalogServiceViaWFCatalog,
		
		getDataCachePath = function( self )
		
			return self:OzCatalogService_getDataCache()
				:tap( function( localDataCache )
				
					dataCache = localDataCache
					
				end )
			
		end,
		
		getDataCachePath = function( self )
		
			local documentsDir = KSPathUtils.getStandardFilePath 'temp'
		
			local catalogDir = KSPathUtils.child( documentsDir, catalog:ozCatalogSpec():catalogId() )
			WFFileUtils.mkdir( catalogDir )
	
			local cachePath = KSPathUtils.child( catalogDir, "previewCache" )
			
			return Rx.Observable.just( cachePath )
			
		end,
		
		test_getWFCatalog = function( self )
		
			return catalog
			
		end,
	}
	local ClClass = Rx.Class( 'OzCatalogService', Cl )
	local catalogService = ClClass( Rx.Observable.just( catalog ) )
	
	local syncClient = LrmSyncClient( catalog, indexSpecScript, 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 dataCache then
			dataCache:haltAndDelete()
				:tapOnCompleted( function()
					syncClient:close()
					catalog:close()
					user:close()
				end )
			:call( runUntilDone )
		
		else
		
			syncClient:close()
			catalog:close()
			user:close()
		
		end
		
	end )

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

	return catalogService, catalog, catalogId, userId
	
end

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

function LrmCatalogTestHelper.makeWFCatalog( mixin, docStorePath )

	assert( type( mixin ) == 'nil', 'No mixin support' )
	
	docStorePath = docStorePath or ':memory:'
	local userInfoCachePath = ':memory:'
	local userId = KSIdGenerator.uuidInLowercaseHex()
	local serverBaseUrl = OzCatalogUrls.baseServerUrl
	local catalogId = KSIdGenerator.uuidInLowercaseHex()
	local rootCatalogPath = KSPathUtils.getStandardFilePath 'temp'
	local indexSpecScript = catalogIndexDefinitions
	
	local catalogOptions = {
		indexSpecScript = indexSpecScript,
		setupConflictResolver = false,
		docStorePath = docStorePath,
		noFileAccessDb = true,
--		docStorePath = KSPathUtils.child( rootCatalogPath, KSIdGenerator.uuidInLowercaseHex() )
	}
	
	debug.print( '------------ %s', catalogId )
	local user = WFCatUser( serverBaseUrl, userId, userInfoCachePath )
	
	local catSpec = WFCatSpec( user, catalogId )
	local catalog = WFCatalog( catSpec, rootCatalogPath, catalogOptions )
	
	rawset( catalog, 'ozCatalogSpec', function()
		return nil -- stubbed out for now
	end )

	return catalog, 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
