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

WFRxIndexStoreSchemaVersionListTest.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2020 Adobe
All Rights Reserved.

NOTICE: All information contained herein is, and remains
the property of Adobe and its suppliers, if any. The intellectual
and technical concepts contained herein are proprietary to Adobe
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.

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

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

	-- WF.core.utils
local KSTableUtils = require 'KSTableUtils'
local WFPlatformInfo = require 'WFPlatformInfo'

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

	-- WF.sqlite.index_store
local WFRxIndexStoreImpUtils = require 'WFRxIndexStoreImpUtils'
local WFRxIndexStoreSchemaVersionList = require 'WFRxIndexStoreSchemaVersionList'

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

-- @mark WFCatVersions namespace

local WFRxIndexStoreSchemaVersionListTest = {}

local validTables = { "versions", "watermark", "album_asset", "conflicts", "faces" }

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

function WFRxIndexStoreSchemaVersionListTest.rxTestBasicSchemaVersionList( rxTest )

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = 0,
		},
		{
			sequence = 1,
			platforms = { "iOS", "Android", "MacOSX", "Windows" },
			tables = { "versions", "watermark" }
		},
		{
			sequence = 2,
			platforms = { WFPlatformInfo.getOS() },
			tables = { "album_asset" }
		},
		{
			sequence = 3,
			platforms = { WFPlatformInfo.isDesktop and "Desktop" or "Mobile" },
			tables = { "conflicts" }
		},
		{
			sequence = 4, -- not this platform
			platforms = { WFPlatformInfo.isDesktop and "Mobile" or "Desktop" },
			tables = { "faces" }
		},
		{
			sequence = 5,
			platforms = { "All" },
			tables = { "faces" }
		},
		-- skip sequence 6, ignored
		{
			sequence = 7,
			platforms = { "All" },
			tables = { "conflicts" }, -- dupes are ignored if they are encountered
		}
	})

	-- start from base sequence
	local newSequence, tables = WFRxIndexStoreSchemaVersionList.getTablesToReindex( 0, validTables )
	rxTest:expectEqual( 7, newSequence )
	rxTest:expectEqual( { "versions", "watermark", "album_asset", "conflicts", "faces" }, tables )

	-- start from later sequence
	newSequence, tables = WFRxIndexStoreSchemaVersionList.getTablesToReindex( 3, validTables )
	rxTest:expectEqual( { "faces", "conflicts" }, tables )

end

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

function WFRxIndexStoreSchemaVersionListTest.rxTestSchemaVersionListBaseLine( rxTest )

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = 2,
			platforms = { WFPlatformInfo.getOS() },
			tables = { "album_asset" },
		},
		{
			sequence = 3,
			platforms = { WFPlatformInfo.isDesktop and "Desktop" or "Mobile" },
			tables = { "conflicts" },
		},
		{
			sequence = 4, -- not this platform
			platforms = { WFPlatformInfo.isDesktop and "Mobile" or "Desktop" },
			tables = { "faces" },
		},
		{
			sequence = 5,
			platforms = { "All" },
			tables = { "faces" },
		},
		-- skip sequence 6, ignored
		{
			sequence = 7,
			platforms = { "All" },
			tables = { "conflicts" }, -- dupes are ignored if they are encountered
		}
	})

	local validTables = { "versions", "watermark", "album_asset", "conflicts", "faces" }

	-- current sequence not included in versions list
	local newSequence, tables = WFRxIndexStoreSchemaVersionList.getTablesToReindex( 0, validTables )
	rxTest:expectEqual( 7, newSequence )
	rxTest:expectEqual( 'hashBasedIndexing', tables )

	-- current sequence is included in versions list
	newSequence, tables = WFRxIndexStoreSchemaVersionList.getTablesToReindex( 3, validTables )
	rxTest:expectEqual( { "faces", "conflicts" }, tables )

	-- There is no current sequence.
	newSequence, tables = WFRxIndexStoreSchemaVersionList.getTablesToReindex( nil, validTables )
	rxTest:expectEqual( 7, newSequence )
	rxTest:expectEqual( 'hashBasedIndexing', tables )

end

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

function WFRxIndexStoreSchemaVersionListTest.rxTestSchemaListErrors( rxTest )

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		"foo",
		"bar",
	})

	-- invalid schema version list
	rxTest:expectError( WFRxIndexStoreSchemaVersionList.getTablesToReindex, 0, validTables,
		"WFRxIndexStoreSchemaVersionList.getTablesToReindex(): invalid schema version list, expected table" )


	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = "not a number",
		},
	})

	-- invalid sequence
	rxTest:expectError( WFRxIndexStoreSchemaVersionList.getTablesToReindex, 0, validTables,
		"WFRxIndexStoreSchemaVersionList.getTablesToReindex(): invalid sequence" )

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = 0,
		},
		{
			sequence = 1,
			platforms = { "iOS", "Android", "MacOSX", "Windows" },
			tables = { "versions", "watermark" },
		},
		{
			sequence = 3,
			platforms = { WFPlatformInfo.getOS() },
			tables = { "album_asset" },
		},
		{
			sequence = 2,
			platforms = { WFPlatformInfo.isDesktop and "Desktop" or "Mobile" },
			tables = { "conflicts" },
		},
	})

	-- invalid sequence
	rxTest:expectError( WFRxIndexStoreSchemaVersionList.getTablesToReindex, 0, validTables,
		"WFRxIndexStoreSchemaVersionList.getTablesToReindex(): invalid sequence" )

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = 0,
		},
				{
			sequence = 1,
			platforms = "foo",
			tables = { "versions", "watermark" },
		},
	})

	-- invalid platforms
	rxTest:expectError( WFRxIndexStoreSchemaVersionList.getTablesToReindex, 0, validTables,
		"WFRxIndexStoreSchemaVersionList.getTablesToReindex(): invalid platforms" )

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = 0,
		},
				{
			sequence = 1,
			platforms = { "foo" },
			tables = { "versions", "watermark" },
		},
	})

	-- invalid platforms
	rxTest:expectError( WFRxIndexStoreSchemaVersionList.getTablesToReindex, 0, validTables,
		"WFRxIndexStoreSchemaVersionList: invalid platform specificer: 'foo'" )

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = 0,
		},
				{
			sequence = 1,
			platforms = { "All" },
			tables = "foo",
		},
	})

	-- invalid platforms
	rxTest:expectError( WFRxIndexStoreSchemaVersionList.getTablesToReindex, 0, validTables,
		"WFRxIndexStoreSchemaVersionList.getTablesToReindex(): tables must be a list" )

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = 0,
		},
		{
			sequence = 1,
			platforms = "All",
			tables = { "foo" },
		},
	})

	-- invalid platforms
	rxTest:expectError( WFRxIndexStoreSchemaVersionList.getTablesToReindex, 0, validTables,
		"WFRxIndexStoreSchemaVersionList.addTables(): invalid table foo for this platform" )

end

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

function WFRxIndexStoreSchemaVersionListTest.rxTestSchemaVersionListWithCatalog( rxTest )

	rxTest:setTimeLimit( 5 )

	-- TODO: adapt this test after adding indexStore method getIndexTables() and getSchemaVersionListSequence()
	-- which will return as observables a list of the index tables and the current schema version list sequence

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = 0,
		},
		{
			sequence = 1,
			platforms = { "All" },
			tables = { "watermark" },
		},
	})

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest )

	local indexStore = wfCatalog:indexStore()

	local obs = rxTest:observe(
				indexStore:DEBUG_getMapFunctionHashes() -- temp. hack to get index tables
					:map( function( hashTable )
						local tableNames = {}
						for _, v in pairs( hashTable ) do
							local tableName, _ = unpack( v )
							tableNames[ #tableNames + 1 ] = tableName
						end
						return tableNames
					end)
					:map( function( indexStoreTables )
						return WFRxIndexStoreSchemaVersionList.getTablesToReindex( 0, indexStoreTables)
					end) )

	obs:expectData( 1, { "watermark" } )

end

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

function WFRxIndexStoreSchemaVersionListTest.rxTestVerifyActualSchemaVersionList( rxTest, createIndexStoreFn )

	-- If the following test fails, it means that the schema version list -- defined within
	-- WFRxIndexStoreSchemaVersionList -- contains an invalid entry and must be fixed.

	local actualSchemaVersionList = WFRxIndexStoreSchemaVersionList.getSchemaVersionList()
	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest, actualSchemaVersionList )

	local indexSpecScript
	
	if WFPlatformInfo.isDesktop then
		indexSpecScript = "WFCatIndexDefinitions.lua"
	else
		indexSpecScript = "LrmCatalogIndexDefinitions.lua"
	end
	
	local indexStoreSchema = WFRxIndexStoreImpUtils.loadSchema( indexSpecScript )
	assert( indexStoreSchema, "Cannot load schema" )
	
	local validTablesSet = indexStoreSchema:tableNames()
	local validTables = KSTableUtils.extractKeys( validTablesSet )
	
	rxTest:expectEqual( true, not not WFRxIndexStoreSchemaVersionList.getTablesToReindex( 0, validTables ) )

end

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

return WFRxTestCase.wrapSuite( WFRxIndexStoreSchemaVersionListTest )
