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

ADOBE CONFIDENTIAL
------------------
Copyright 2022 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 KSIdGenerator = require 'KSIdGenerator'
local WFPlatformInfo = require 'WFPlatformInfo'
local KSTableUtils = require 'KSTableUtils'

    -- WF.oz_client.managed_catalog
local WFCatAssetAux = require 'WFCatAssetAux'
local WFCatAssetTestUtils = require 'WFCatAssetTestUtils'
local WFCatFileSpec = require 'WFCatFileSpec'
local WFCatMockCatalog = require 'WFCatMockCatalog'

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

local WFCatFileSpecTest = {}

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

local _wfCatalog

local function createFakeWFCatalogForTestSuite( rxTest )

	if not _wfCatalog then

		local optArgs = {
			keepOpenAfterTestFinishes = true
		}
		
		if WFPlatformInfo.isMobile() then
			optArgs.indexDefinitions = 'LrmCatalogIndexDefinitions.lua'
		end

		_wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest , nil, nil, optArgs )
	
	end
	
	return _wfCatalog
	
end

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

local function buildDocValue( rxTest, overrides )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	local wfCatalog = createFakeWFCatalogForTestSuite( rxTest )
	
	local docValue, expectedData = WFCatAssetTestUtils.createAssetDocument( rxTest, wfCatalog, assetId, overrides )

	return docValue, expectedData, wfCatalog

end

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

function WFCatFileSpecTest.rxTestGetProxyLinkFromDocValue( rxTest )

	-- Image

	local overrides = {}

	local docValue = buildDocValue( rxTest )

	local link, proxySize, isInvalid = WFCatFileSpec.getProxyLinkFromDocValue( docValue )
	
	rxTest:expectEqual( true, not not link )
	rxTest:expectEqual( '2560', proxySize )
	rxTest:expectEqual( nil, isInvalid )
	
	-- Image (2560)
	
	docValue = buildDocValue( rxTest, overrides )

	link, proxySize, isInvalid = WFCatFileSpec.getProxyLinkFromDocValue( docValue, '2560' )
	
	rxTest:expectEqual( true, not not link )
	rxTest:expectEqual( '2560', proxySize )
	rxTest:expectEqual( nil, isInvalid )
		
	-- Invalid Link
	
	overrides = {
		ozProxiesAreInvalid = true
	}
	
	docValue = buildDocValue( rxTest, overrides )

	link, proxySize, isInvalid = WFCatFileSpec.getProxyLinkFromDocValue( docValue )
	
	rxTest:expectEqual( true, not not link )
	rxTest:expectEqual( '2560', proxySize )
	rxTest:expectEqual( true, isInvalid )
	
	-- Image (Panorama)
	
	overrides = {
		isPanorama = true
	}
	
	docValue = buildDocValue( rxTest, overrides )
	
	link, proxySize, isInvalid = WFCatFileSpec.getProxyLinkFromDocValue( docValue, 'panorama' )
	
	rxTest:expectEqual( true, not not link )
	rxTest:expectEqual( 'panorama', proxySize )
	rxTest:expectEqual( nil, isInvalid )
	
	-- Image (Fullsize)
	
	overrides = {
		hasLocalFullsizeProxy = true
	}
	
	docValue = buildDocValue( rxTest, overrides )
	
	link, proxySize, isInvalid = WFCatFileSpec.getProxyLinkFromDocValue( docValue, 'fullsize' )
	
	rxTest:expectEqual( true, not not link )
	rxTest:expectEqual( 'fullsize', proxySize )
	rxTest:expectEqual( nil, isInvalid )

	-- No Proxy Links
	
	overrides = {
		noProxyLink = true
	}
	
	docValue = buildDocValue( rxTest, overrides )
	
	link = WFCatFileSpec.getProxyLinkFromDocValue( docValue )
	
	rxTest:expectEqual( nil, link )
	
	-- Video (Default)
	
	overrides = {
		docSubtype = 'video'
	}
	
	local platfromDefault = WFPlatformInfo.isWindows and "1080p709" or "1080p"
	
	docValue = buildDocValue( rxTest, overrides )
	
	link, proxySize, isInvalid = WFCatFileSpec.getProxyLinkFromDocValue( docValue )
	
	rxTest:expectEqual( true, not not link )
	rxTest:expectEqual( platfromDefault, proxySize )
	rxTest:expectEqual( nil, isInvalid )
	
	-- Video (1080p)
	
	overrides = {
		docSubtype = 'video',
	}
	
	docValue = buildDocValue( rxTest, overrides )
	
	link, proxySize, isInvalid = WFCatFileSpec.getProxyLinkFromDocValue( docValue, '1080p' )
	
	rxTest:expectEqual( true, not not link )
	rxTest:expectEqual( '1080p', proxySize )
	rxTest:expectEqual( nil, isInvalid )
	
	-- Video (1080p709)
	
	overrides = {
		docSubtype = 'video',
	}
	
	docValue = buildDocValue( rxTest, overrides )
	
	link, proxySize, isInvalid = WFCatFileSpec.getProxyLinkFromDocValue( docValue, '1080p709' )
	
	rxTest:expectEqual( true, not not link )
	rxTest:expectEqual( '1080p709', proxySize )
	rxTest:expectEqual( nil, isInvalid )
	
	-- Video (720p)
	
	overrides = {
		docSubtype = 'video',
	}
	
	docValue = buildDocValue( rxTest, overrides )
	
	link, proxySize, isInvalid = WFCatFileSpec.getProxyLinkFromDocValue( docValue, '720p' )

	rxTest:expectEqual( true, not not link )
	rxTest:expectEqual( '720p', proxySize )
	rxTest:expectEqual( nil, isInvalid )
	
	-- Video (360p)
	
	overrides = {
		docSubtype = 'video',
	}
	
	docValue = buildDocValue( rxTest, overrides )
	
	link, proxySize, isInvalid = WFCatFileSpec.getProxyLinkFromDocValue( docValue, '360p' )

	rxTest:expectEqual( true, not not link )
	rxTest:expectEqual( '360p', proxySize )
	rxTest:expectEqual( nil, isInvalid )
	
	-- Video, No Local Proxy
	
	overrides = {
		docSubtype = 'video',
		noProxyLink = true
	}
	
	docValue = buildDocValue( rxTest, overrides )
	
	link = WFCatFileSpec.getProxyLinkFromDocValue( docValue )
	
	rxTest:expectEqual( nil, link )

end

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

function WFCatFileSpecTest.rxTestGetProxySizeFromDocValue( rxTest )

	-- Image
	
	local overrides = {}
	
	local docValue, expectedData = buildDocValue( rxTest )

	local result = WFCatFileSpec.getProxySizeFromDocValue( docValue )
	
	rxTest:expectEqual( expectedData.proxyFileSize, result )
	
	-- Image (2560)
	
	overrides = {
		hasLocal2560Proxy = true
	}
	
	docValue, expectedData = buildDocValue( rxTest, overrides )
	
	result = WFCatFileSpec.getProxySizeFromDocValue( docValue, '2560' )

	rxTest:expectEqual( expectedData.proxyFileSize, result )
	
	-- Image (Panorama)
	
	overrides = {
		isPanorama = true
	}
	
	docValue, expectedData = buildDocValue( rxTest, overrides )
	
	result = WFCatFileSpec.getProxySizeFromDocValue( docValue, 'panorama' )

	rxTest:expectEqual( expectedData.proxyFileSize, result )
	
	-- Image (Fullsize)
	
	overrides = {
		hasLocalFullsizeProxy = true
	}
	
	docValue, expectedData = buildDocValue( rxTest, overrides )
	
	result = WFCatFileSpec.getProxySizeFromDocValue( docValue, 'fullsize' )

	rxTest:expectEqual( expectedData.fullsizeProxyFileSize, result )

	-- No Local Proxy
	
	overrides = {
		noLocalProxy = true
	}
	
	docValue, expectedData = buildDocValue( rxTest, overrides )
	
	result = WFCatFileSpec.getProxySizeFromDocValue( docValue )
	
	rxTest:expectEqual( nil, result )
	
	-- Video (Default)
	
	overrides = {
		docSubtype = 'video'
	}
	
	docValue, expectedData = buildDocValue( rxTest, overrides )
	
	result = WFCatFileSpec.getProxySizeFromDocValue( docValue )
	
	rxTest:expectEqual( expectedData.proxy1080pFileSize, result )
	
	-- Video (1080p)
	
	overrides = {
		docSubtype = 'video',
		hasLocal1080p = true
	}
	
	docValue, expectedData = buildDocValue( rxTest, overrides )
	
	result = WFCatFileSpec.getProxySizeFromDocValue( docValue, '1080p' )
	
	rxTest:expectEqual( expectedData.proxy1080pFileSize, result )
	
	-- Video (720p)

	overrides = {
		docSubtype = 'video',
		hasLocal720p = true
	}
	
	docValue, expectedData = buildDocValue( rxTest, overrides )
	
	result = WFCatFileSpec.getProxySizeFromDocValue( docValue, '720p' )
	
	rxTest:expectEqual( expectedData.proxy720pFileSize, result )
	
	-- Video (360p)
	
	overrides = {
		docSubtype = 'video',
		hasLocal360p = true
	}
	
	docValue, expectedData = buildDocValue( rxTest, overrides )
	
	result = WFCatFileSpec.getProxySizeFromDocValue( docValue, '360p' )
	
	rxTest:expectEqual( expectedData.proxy360pFileSize, result )
	
	-- Video, No Local Proxy
	
	overrides = {
		docSubtype = 'video',
		noLocalProxy = true
	}
	
	docValue, expectedData = buildDocValue( rxTest, overrides )
	
	result = WFCatFileSpec.getProxySizeFromDocValue( docValue )
	
	rxTest:expectEqual( nil, result )

end

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

function WFCatFileSpecTest.rxTestGetSelfLinkFromDocValue( rxTest )

	local overrides = {}

	local docValue = buildDocValue( rxTest, overrides )

	local result = WFCatFileSpec.getSelfLinkFromDocValue( docValue )

	local expected = "/href/bogus/self"

	rxTest:expectEqual( expected, result )

end

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

function WFCatFileSpecTest.rxTestGetTableOfAuxLinksFromDocValue( rxTest )

	-- No Masks

	local overrides = {}

	local docValue, expectedData = buildDocValue( rxTest, overrides )

	local result = WFCatFileSpec.getTableOfAuxLinksFromDocValue( docValue )

	local expected = nil

	rxTest:expectEqual( expected, result )

	-- Masks, No Links

	overrides = {
		hasMasks = true,
		noMaskLinks = true
	}

	docValue, expectedData = buildDocValue( rxTest, overrides )

	result = WFCatFileSpec.getTableOfAuxLinksFromDocValue( docValue )

	rxTest:expectEqual( expected, result )

	-- Masks With Links

	overrides = {
		hasMasks = true
	}

	docValue, expectedData = buildDocValue( rxTest, overrides )

	result = WFCatFileSpec.getTableOfAuxLinksFromDocValue( docValue )

	expected = {
		[ expectedData.mask1Fingerprint ] = WFCatAssetAux.getDownloadLink( docValue, expectedData.mask1Fingerprint ),
		[ expectedData.mask2Fingerprint ] = WFCatAssetAux.getDownloadLink( docValue, expectedData.mask2Fingerprint ),
	}

	rxTest:expectEqual( expected, result )

	-- c2pa, no link

	overrides = {
		hasC2pa = true,
		noC2paLink = true
	}

	docValue, expectedData = buildDocValue( rxTest, overrides )

	result = WFCatFileSpec.getTableOfAuxLinksFromDocValue( docValue )

	rxTest:expectEqual( nil, result )

	-- c2pa with link

	overrides = {
		hasC2pa = true
	}

	docValue, expectedData = buildDocValue( rxTest, overrides )

	result = WFCatFileSpec.getTableOfAuxLinksFromDocValue( docValue )

	expected = {
		[ expectedData.c2paFingerprint ] = WFCatAssetAux.getDownloadLink( docValue, expectedData.c2paFingerprint ),
	}

	rxTest:expectEqual( expected, result )

	-- hasFilters, no link

	overrides = {
		hasFilters = true,
		noFilterLinks = true,
	}

	docValue, expectedData = buildDocValue( rxTest, overrides )

	result = WFCatFileSpec.getTableOfAuxLinksFromDocValue( docValue )

	rxTest:expectEqual( nil, result )

	-- hasFilters with link

	overrides = {
		hasFilters = true,
	}

	docValue, expectedData = buildDocValue( rxTest, overrides )

	result = WFCatFileSpec.getTableOfAuxLinksFromDocValue( docValue )

	expected = {
		[ expectedData.filter1Fingerprint ] = WFCatAssetAux.getDownloadLink( docValue, expectedData.filter1Fingerprint ),
		[ expectedData.filter2Fingerprint ] = WFCatAssetAux.getDownloadLink( docValue, expectedData.filter2Fingerprint ),
	}

	rxTest:expectEqual( expected, result )

end

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

function WFCatFileSpecTest.rxTestOzOriginalLinks( rxTest )

	for _, corruptMaster in ipairs( { false, true } ) do
	
		for _, masterLinkState in ipairs( { 'none', 'valid', 'invalid' } ) do

			for _, localOnlyError in ipairs( { false, 'binaryUploadErrors', 'binaryDownloadErrors' } ) do

				local docValue = 
						buildDocValue( rxTest, 
							{

								corruptMaster = corruptMaster or nil,

								noMasterLink = masterLinkState == 'none' or nil,

								ozOriginalIsInvalid = masterLinkState == 'invalid' or nil,

							} )

				if localOnlyError then

					KSTableUtils.setNested( docValue, {}, '_localOnly', localOnlyError, '/rels/master' )

					local maybeOzOriginalLink = KSTableUtils.derefOpt( docValue, '_serverProvidedMetadata', 'links', '/rels/master', 'href' )

					if maybeOzOriginalLink then

						KSTableUtils.setNested( docValue, true, '_localOnly', localOnlyError, '/rels/master', maybeOzOriginalLink )

					end

				end

				rxTest:logf( "testing corruptMaster == %s, masterLinkState == %s, localOnlyError == %s",
								corruptMaster, masterLinkState, localOnlyError )

				local maybeOriginalLink, isInvalid, maybeInvalidOriginalLink =
						WFCatFileSpec.getOriginalLinkFromDocValue( docValue )

				local actuallyHaveOrigLink = maybeOriginalLink ~= nil

				local expectedHaveOrigLink = 
						not corruptMaster and masterLinkState ~= 'none' and not localOnlyError 

				rxTest:expectEqual( expectedHaveOrigLink, actuallyHaveOrigLink )

				local expectedIsInvalid =
					( masterLinkState == 'none' and corruptMaster ) or
					( masterLinkState == 'valid' and corruptMaster and localOnlyError == false ) or
					( masterLinkState == 'invalid' and localOnlyError == false ) or
					nil

				rxTest:logf( "expectedIsInvalid == %s, actual %s", expectedIsInvalid, isInvalid )

				rxTest:expectEqual( expectedIsInvalid, isInvalid )

				local actuallyHaveInvalidOrigLink = maybeInvalidOriginalLink ~= nil

				local expectedHaveInvalidOrigLink = 
						masterLinkState ~= 'none' and not localOnlyError and 
							( corruptMaster or masterLinkState == 'invalid' ) 

				rxTest:expectEqual(
						expectedHaveInvalidOrigLink, actuallyHaveInvalidOrigLink )

			end

		end

	end

end

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

function WFCatFileSpecTest.rxTestZZ_CloseSuite( rxTest )

	-- Funky naming means this runs last in the suite.

	rxTest:finally( function()
	
		if _wfCatalog then
		
			_wfCatalog:close()
			_wfCatalog = nil
	
		end
	
	end )
	
end

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

if WFPlatformInfo.isDesktop then
	return WFRxTestCase.wrapSuite( 'WFCatFileSpecTest', WFCatFileSpecTest )
else
	return {}
end
