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

WFCatMockCatalog.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.

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

	-- RxLua
local Rx = require 'Rx'

	-- WF.core.self_test
local WFTestFileUtils = require 'WFTestFileUtils'

	-- WF.core.utils
local KSPathUtils = require 'KSPathUtils'
local WFCatPixelPathGenerator = require 'WFCatPixelPathGenerator'
local WFCloseSupport = require 'WFCloseSupport'
local WFFileUtils = require 'WFFileUtils'
local KSIdGenerator = require 'KSIdGenerator'
local WFObjectProxy = require 'WFObjectProxy'

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

local WFCatMockCatalog = {}

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

local kOzUserId = 'abad1dea00000000abad1dea00000000'
local kOzCatalogId = 'c1737ec7bfe942dd95d8c733f682b5df'

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

local WFCatFileSpecMock = {
	_basePath = false,
	_docStorePath = false,
	WFCloseSupport.addCloseSupportMethods,
}

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

function WFCatFileSpecMock:__init( basePath, docStorePath )
	self._basePath = basePath
	self._docStorePath = docStorePath
	WFFileUtils.mkdir( basePath )
end

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

function WFCatFileSpecMock:pixelsPath() 
	local path =  KSPathUtils.child( self._basePath, 'renditionsPath' )
	WFFileUtils.mkdir( path )
	return path
end

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

function WFCatFileSpecMock:catalogPath()
	local path = KSPathUtils.child( self._basePath, 'catalogPath' )
	WFFileUtils.mkdir( path )
	return path
end

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

function WFCatFileSpecMock:docStorePath()
	return self._docStorePath or ':memory:'
end

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

function WFCatFileSpecMock:fileAccessDbPath()
	return ':memory:'
end

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

function WFCatFileSpecMock:rootPath( )
	return self._basePath
end

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

function WFCatFileSpecMock:catalogPathInfo()
	
	local volumeGuid = WFFileUtils.getVolumeGuidForPath( self._basePath )
	local relativePath = WFFileUtils.removeVolumeFromPath( self._basePath )
	
	return {
		volumeGuid = volumeGuid,
		relativePath = relativePath,
	}
	
end

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

function WFCatFileSpecMock:tempFolderPathForVolume()
	
	local tempFolder = KSPathUtils.getStandardFilePath( "temp" )
	pcall( WFFileUtils.mkdir, tempFolder )
	
	return tempFolder
	
end

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

function WFCatFileSpecMock:originalsPathInfo()
	
	local volumeGuid = WFFileUtils.getVolumeGuidForPath( self._basePath )
	local relativePath = WFFileUtils.removeVolumeFromPath( self._basePath )
	
	return {
		volumeGuid = volumeGuid,
		relativePath = relativePath,
	}
	
end

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

function WFCatFileSpecMock:proxiesPathInfo()

	local volumeGuid = WFFileUtils.getVolumeGuidForPath( self._basePath )
	local relativePath = WFFileUtils.removeVolumeFromPath( self._basePath )
	
	return {
		volumeGuid = volumeGuid,
		relativePath = relativePath,
	}
	
end

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

function WFCatFileSpecMock:pathForOriginal( fileName, captureDate )
	
	return WFCatPixelPathGenerator.pathForOriginal( self._basePath, fileName, captureDate )
	
end

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

function WFCatFileSpecMock:pathForProxy( assetId, proxyType )

	return WFCatPixelPathGenerator.pathForProxyTypeAndUuid( self._basePath, proxyType, assetId )
	
end

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

function WFCatFileSpecMock:pathForXmpSidecar( assetId )

	return WFCatPixelPathGenerator.pathForXmpSidecar( self._basePath, assetId )

end

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

function WFCatFileSpecMock:folderForSettingsXmp( )

	return WFCatPixelPathGenerator.folderForSettingsXmp( self:pixelsPath() )

end

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

function WFCatFileSpecMock:pathForSettingsXmp( sha256 )

	return WFCatPixelPathGenerator.pathForSettingsXmp( self:pixelsPath(), sha256 )

end

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

function WFCatFileSpecMock:pathForStyle( assetId )
	
	return WFCatPixelPathGenerator.pathForStyle( self:pixelsPath(), assetId )
	
end

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

function WFCatFileSpecMock:maybeStylePath( path )
	
	return WFCatPixelPathGenerator( self:pixelsPath(), path )

end

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

function WFCatFileSpecMock:pathForPreviewDigestAndLongEdge( uuid, digest, longEdge, optCreateDirectory )

	return WFCatPixelPathGenerator.pathForPreviewDigestAndLongEdge( self._basePath,
		uuid, digest, longEdge, optCreateDirectory )

end

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

function WFCatFileSpecMock:close() 
	WFFileUtils.deleteDirectory( self._basePath )
end

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

WFCatFileSpecMock = Rx.Class( 'WFCatFileSpec', WFCatFileSpecMock )

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

local function getUniqueBasePath( rxTest )

	return KSPathUtils.child(
				KSPathUtils.child( 
					KSPathUtils.getStandardFilePath( 'temp' ), 
					KSIdGenerator.uuidInLowercaseHex() ),
				rxTest:testName() )

end

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

local fakeWFCatalog = Rx.Class 'WFCatalog' {
	_docStore = false,
	_indexStore = false,
	_mruDatabase = false,
	_ozUserId = false,
	_searchSchema = false,
	_fileSpec = false,
	_catSpec = false,
	_volumeAgents = false,
	_albumsCache = false,
	
	WFCloseSupport.addCloseSupportMethods,

	__init = function( self, rxTest, ozUserId, optDocStorePath, optRequestResponsePairs, optIndexDefinitions, optArgs )
	
		local WFRxDocStore = require 'WFRxDocStore'
		local WFRxIndexStore = require 'WFRxIndexStore'
		local NmbMRUDatabase = require 'NmbMRUDatabase'
		
		local docStorePath = optDocStorePath

		if not docStorePath then
		
			docStorePath = ':memory:' .. tostring( KSIdGenerator.localCounter() )
		
		end
		
		local basePath = getUniqueBasePath( rxTest )
		local fileSpec = WFCatFileSpecMock( basePath, docStorePath )
		
		local docStore = WFRxDocStore( docStorePath )
		local indexStore = WFRxIndexStore( docStore, optIndexDefinitions or 'WFCatIndexDefinitions.lua' )
		
		optArgs = optArgs or {}
		optArgs.writeInterval = optArgs.writeInterval or 0.1
		optArgs.doNotInitialize = true
		optArgs.isDebugMode = true
		
		local mruDatabase = NmbMRUDatabase( docStorePath,
										optIndexDefinitions or 'WFCatIndexDefinitions.lua',
										fileSpec:fileAccessDbPath(),
										optArgs )
		
		local searchSchema = require 'WFCatSearchSchema'()
		require 'WFCatSearchHandler'.addSearchToSearchSchema( searchSchema )
		require 'WFCatIdleDownloader'.addSearchToSearchSchema( searchSchema )
		
		self._ozUserId = ozUserId
		self._searchSchema = searchSchema
		self._volumeAgents = {}
		
		self._catSpec = require 'WFCatSpecMock'( '98db98bfd554470dab2f862a4b853c40', '04c358b4a268f2bad074455dfb89bd89', rxTest, optRequestResponsePairs or {} )
		
		WFTestFileUtils.addTestFolder( basePath )

		self:setOwned {
			_docStore = docStore,
			_indexStore = indexStore,
			_mruDatabase = mruDatabase,
			_fileSpec = fileSpec,
		}

	end,
	docStore = function( self )
		return self._docStore
	end,
	indexStore = function( self )
		return self._indexStore
	end,
	fileAccessDb = function( self )
		return self._mruDatabase
	end,
	mruDatabase = function( self )
		return self._mruDatabase
	end,
	ozUserId = function( self )
		return self._ozUserId
	end,
	ozUser = function( self )
		return {
			purgeAssetsAfterValue = function() return Rx.Observable.just( 60*24*60*60 ) end,
			mapPartialUrlToCompleteUrl = function( _, url ) 
				return string.format( "https://photos.adobe.io/v2%s", url )
			end
		}
	end,
	ozCatalogId = function( self )
		return kOzCatalogId
	end,
	searchSchema = function( self )
		return self._searchSchema
	end,
	fileSpec = function( self )
		return self._fileSpec
	end,
	ozCatalogSpec = function( self )
		return self._catSpec
	end,
	relayObject = function( self )
		return self
	end,
	getAllVolumeAgents = function( self )
		return self._volumeAgents
	end,
	getDeletionBacklog = function( self )
		return self._mruDatabase
	end,
	addVolumeAgent = function( self, volumeAgent )
		self._volumeAgents[ volumeAgent:getVolumeGuid() ] = volumeAgent
	end,
	albumsCache = function( self )
		if not self._albumsCache then
			local albumsCache = require 'NmbAlbumsCache'( self )
			self:setOwned {
				_albumsCache = albumsCache
			}		
		end
		return self._albumsCache
	end
}

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

function WFCatMockCatalog.createFakeWFCatalog( rxTest, optDocStorePath, optRequestResponsePairs, optArgs )

	optArgs = optArgs or {}

	local fakeWFCatalogClass = WFObjectProxy( 'WFCatalog', fakeWFCatalog, nil, true )

	local optIndexDefinitions = optArgs.indexDefinitions

	local result = fakeWFCatalogClass( rxTest, kOzUserId, optDocStorePath, optRequestResponsePairs, optIndexDefinitions, optArgs )

	if not optArgs.keepOpenAfterTestFinishes then
	
		rxTest:finally( function()
			result:close()
		end )
		
	end

	return result

end

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

function WFCatMockCatalog.createWFCatalogForTestWithSpec( rxTest, wfCatalogSpec, optCatalogClassType, optIndexSpecScript )
	
	local basePath = getUniqueBasePath( rxTest )
	
	local optArgs = {
		docStorePath = ':memory:',
		fileAccessDbPath = ':memory:',
		indexSpecScript = optIndexSpecScript,
	}
	
	local catalog = require ( optCatalogClassType or 'WFCatalog' )( wfCatalogSpec, basePath, optArgs )

	rxTest:finally( function()
		catalog:close() -- closing the catalog will delete the basePath
	end )
	
	return catalog
end

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

function WFCatMockCatalog.createWFCatalogForProfiles( rxTest, wfCatalogSpec, indexSpecScript, optCatalogClassType )
	
	local basePath = getUniqueBasePath( rxTest )
	
	local optArgs = {
		docStorePath = ':memory:',
		fileAccessDbPath = ':memory:',
		indexSpecScript = indexSpecScript,
	}
	
	local catalog = require ( optCatalogClassType or 'WFCatalog' )( wfCatalogSpec, basePath, optArgs )

	rxTest:finally( function()
		catalog:close() -- closing the catalog will delete the basePath
	end )
	
	return catalog
end

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

return WFCatMockCatalog
