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

WFCatTestSessionTest.lua

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

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.

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

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

	-- WF.core.utils
local KSDate = require 'KSDate'
local WFArguments = require 'WFArguments'
local WFRxRunUntilDone = require 'WFRxRunUntilDone'

	-- WF.oz_client.managed_catalog
local WFCatTestSession = require 'WFCatTestSession'


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

local check = assert( WFArguments.check )

local runUntilDone = WFRxRunUntilDone

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

local WFCatTestSessionTest = {}

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

function WFCatTestSessionTest.rxTestOzUserConstruction_testNightly( rxTest )

	rxTest:setTimeLimit( 30 )

	local catalogTestSession = WFCatTestSession( rxTest )

	local ozUserId

	rxTest:expectSingleValue(

		catalogTestSession:ozUserId()
			:map( function( _ozUserId )
				ozUserId = _ozUserId
				return ozUserId, type( ozUserId ), type( ozUserId ) == 'string' and #ozUserId
			end ),

		':ignore:', 'string', 32 )

	-- Make sure we provide the same answer to subsequent subscribers.

	rxTest:expectSingleValue(
		catalogTestSession:ozUserId(),
		ozUserId )

	local wfCatUser

	rxTest:expectSingleValue(

		catalogTestSession:wfCatUser()
			:map( function( ozUser )
				check( 'WFCatUser' )
				wfCatUser = ozUser
				return tostring( ozUser ), ozUser:userId()
			end ),

		':ignore:', ozUserId )

	rxTest:expectSingleValue(
		catalogTestSession:wfCatUser(),
		wfCatUser )

	local wfCatSpec

	rxTest:expectSingleValue(

		catalogTestSession:catalogSpec()
			:map( function( catalogSpec )
				check( 'WFCatSpec' )
				wfCatSpec = catalogSpec
				return tostring( catalogSpec ), catalogSpec:catalogId()
			end ),

		':ignore:', ':ignore:' )

	rxTest:expectSingleValue(
		catalogTestSession:catalogSpec(),
		wfCatSpec )

	local wfCatalog

	rxTest:expectSingleValue(

		catalogTestSession:catalog()
			:map( function( catalog )
				check( 'WFCatalog' )
				wfCatalog = catalog
				return tostring( catalog ), catalog:ozCatalogSpec()
			end ),

		':ignore:', wfCatSpec )

	rxTest:expectSingleValue(
		catalogTestSession:catalog(),
		wfCatalog )

	-- Make sure it has a valid doc store.

	local docStore = wfCatalog:docStore()

	rxTest:expectSingleValue(

		docStore:setDocValue {
			_id = 'testDoc',
			foo = 'bar',
		},

		':ignore:' )

end

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

function WFCatTestSessionTest.rxTestTooManyOzCatalogs_testNightly( rxTest )

	rxTest:setTimeLimit( 30 )

	-- Create the Test Session
	
	local catalogTestSession = WFCatTestSession( rxTest )

	-- Get the wfCatUser object.
	
	local wfCatUser

	rxTest:waitFor(

		catalogTestSession:wfCatUser()
			:map( function( ozUser )
				check( 'WFCatUser' )
				wfCatUser = ozUser
				return
			end ) )

	-- Get the Catalog Spec. This has the side effect of creating a catalog on Oz.

	local wfCatSpec

	rxTest:waitFor(

		catalogTestSession:catalogSpec()
			:map( function( catalogSpec )
				check( 'WFCatSpec' )
				wfCatSpec = catalogSpec
				return
			end ) )

	-- Now attempt to create a new catalog. It should return the existing catalog,
	-- since we now properly handle the TooManyOzCatalogs error.

	rxTest:expectSingleValue( 
	
		wfCatUser:createCatalog( "WFCatTestSession" ),
		
		wfCatSpec
	
	)


end

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

function WFCatTestSessionTest.rxTestCatalogCreationDelay_testNightly( rxTest )

	rxTest:setTimeLimit( 30 )

	-- Create the Test Session
	
	local catalogTestSession = WFCatTestSession( rxTest )

	-- Get the wfCatUser object.
	
	local wfCatUser = rxTest:getFirstValue( catalogTestSession:wfCatUser() )

	-- Create a catalog on Oz without out waiting for it to complete.

	local startTime = KSDate.timeNow()
	local endTime 
	
	local wfCatSpec1
	
	wfCatUser:findOrCreateCatalog( "rxTestCatalogCreationDelay_testNightly" )
		:map( function( wfCatSpec )
			wfCatSpec1 = wfCatSpec
		end )
		:call( runUntilDone )
	
	-- Now attempt to quickly find/create a new catalog. The new logic should add in a 5 second delay
	-- before attempting to find the catalog. This delay should make it so that we're guaranteed
	-- to find the catalog created above.
	
	rxTest:expectSingleValue( wfCatUser:findOrCreateCatalog( "rxTestCatalogCreationDelay_testNightly" )
		:map( function( wfCatSpec )
			endTime = KSDate.timeNow()
			return wfCatSpec1._catalogId == wfCatSpec._catalogId -- Verify that both calls return the same catalog.
		end ), true )

	-- Verify that there was at least a 5 second delay between the calls to find/create a catalog.
	
	rxTest:expectEqual( endTime - startTime > 5, true )

end

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

--[[ TODO Rx-ify
function WFCatTestSessionTest.testCatalogTestSession_testNightly( test )

	local catalogTestSession = WFCatTestSession( 'WFCatTestSessionTest' )
	catalogTestSession:setTestName( test:testName() )

	local catalogSpec
	local expectedHrefAndId = { idLength = 32 }

	WFAsyncTestCase( test, 240 )

		:waitFor( function()

			return catalogTestSession:catalogSpecP()
				:observeP( function( _, _catalogSpec )
					catalogSpec = _catalogSpec
				end )

		end )

		:waitFor( function()

			local id = catalogSpec:catalogId()
			local href = catalogSpec:catalogHref()

			expectedHrefAndId.id = id
			expectedHrefAndId.href = "/v2/catalogs/" .. id

			return KSPromises.resolvedPromiseP( 'data',
				{
					idLength = #id,
					id = id,
					href = href,
				} )

		end )
		:continueWhenValueMatches( 'data', expectedHrefAndId )

		:waitFor( function()

			return catalogTestSession:catalogSpecWithThreePhotosP()
				:mapDataP( function( _, catalogSpec )

					return 'data', WFOzCatalogSpec:isClassOf( catalogSpec )

				end )

		end )
		:continueWhenValueMatches( 'data', true )

		:waitFor( function()

			return catalogTestSession:releaseTestUserP()

		end )

end
]]--

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

return WFRxTestCase.wrapSuite( WFCatTestSessionTest )
