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

ADOBE CONFIDENTIAL
------------------
Copyright 2016 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.

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

	-- RxLua
local Rx = require 'Rx'

	-- WF.core.self_test
local WFAsyncTestCase = require 'WFAsyncTestCase'
local LrmCatalogTestHelper = require 'LrmCatalogTestHelper'

	-- WF.core.utils
local KSIdGenerator = require 'KSIdGenerator'

local WFRxPromiseBridge = require "WFRxPromiseBridge"


	-- WF.lrmobile
local LrmDevelopModel = require 'LrmDevelopModel'
local LrmConfig = require 'LrmConfig'

local asKSPromise = WFRxPromiseBridge

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

-- @mark LrmDevelopModelTest namespace

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

local LrmDevelopModelTest = {}

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

local catalog
local mockCatalog

local kOriginalPath = '/original/path'
local kProxyPath = '/proxy/path'
local TEST_TIMEOUT = 10

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

local function createAsset( assetId, shared, contributed )

	local spm = nil
	if not contributed then
		spm = {
			importedByUser = {
				id = "a friend"
			}
		}
	end

	local doc = {
		subtype = 'image',
		captureDate = '2004-11-09',
		_spaceId = shared and "shared_space_id" or nil,
		_serverProvidedMetadata = spm,
		importSource = {
			fileName = 'Image01.jpg',
			originalWidth = 1200,
			originalHeight = 1000,
			sha256 = "abc",
		},
		develop = {
			croppedHeight = 150,
			croppedWidth = 150,
			xmpCameraRaw = '<xmp />',
			userOrientation = 2,
		},
	}
	
	return mockCatalog:docStore():applyOverlayToDocumentP {
						docId = assetId,
						docType = 'asset',
						overlay = doc
					}

end

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

function LrmDevelopModelTest.setUp()

	catalog = Rx.Class( 'OzCatalogService', {
	
		originalDataPathP = function( assetId )
		
			return kOriginalPath
		
		end,
		
		proxyDataPathP = function( assetId, doNotFetch, size )
		
			return kProxyPath
			
		end
			
			
	} )()
	
	
	mockCatalog = LrmCatalogTestHelper.makeCatalogService()
end

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

function LrmDevelopModelTest.tearDown()

	if mockCatalog then
		
		mockCatalog:close()
		
	end
	
end

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

function LrmDevelopModelTest.testRequestPreferProxyBothAvailable( test )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	local developInfo = {
		hasMaster = true,
		originalPath = kOriginalPath,
		hasProxy = true,
		proxyPath = kProxyPath,
	}
	
	local binaryPreference = LrmConfig.StrategyPreferProxy
	
	WFAsyncTestCase( test )
	
		:waitFor( function()
		
			return LrmDevelopModel.requestBinaryP( catalog, assetId, binaryPreference, developInfo )
			
		end )
		
		:continueWhenValueMatches( 'data', kProxyPath, false )
	
end

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

function LrmDevelopModelTest.testRequestPreferMasterBothAvailable( test )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	local developInfo = {
		hasMaster = true,
		originalPath = kOriginalPath,
		hasProxy = true,
		proxyPath = kProxyPath,
	}
	
	local binaryPreference = LrmConfig.StrategyPreferMaster
	
	WFAsyncTestCase( test )
	
		:waitFor( function()
		
			return LrmDevelopModel.requestBinaryP( catalog, assetId, binaryPreference, developInfo )
			
		end )
		
		:continueWhenValueMatches( 'data', kOriginalPath, true )
	
end

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

function LrmDevelopModelTest.testRequestPreferProxyOnlyMasterAvailable( test )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	local developInfo = {
		hasMaster = true,
		originalPath = kOriginalPath,
		hasProxy = false,
		proxyPath = nil,
	}
	
	local binaryPreference = LrmConfig.StrategyPreferProxy
	
	WFAsyncTestCase( test )
	
		:waitFor( function()
		
			return LrmDevelopModel.requestBinaryP( catalog, assetId, binaryPreference, developInfo )
			
		end )
		
		:continueWhenValueMatches( 'data', kOriginalPath, true )
	
end

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

function LrmDevelopModelTest.testRequestPreferProxyOnlyProxyAvailable( test )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	local developInfo = {
		hasMaster = false,
		originalPath = nil,
		hasProxy = true,
		proxyPath = kProxyPath,
	}
	
	local binaryPreference = LrmConfig.StrategyPreferProxy
	
	WFAsyncTestCase( test )
	
		:waitFor( function()
		
			return LrmDevelopModel.requestBinaryP( catalog, assetId, binaryPreference, developInfo )
			
		end )
		
		:continueWhenValueMatches( 'data', kProxyPath, false )
	
end

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

function LrmDevelopModelTest.testRequestPreferMasterOnlyProxyAvailable( test )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	local developInfo = {
		hasMaster = false,
		originalPath = nil,
		hasProxy = true,
		proxyPath = kProxyPath,
	}
	
	local binaryPreference = LrmConfig.StrategyPreferMaster
	
	WFAsyncTestCase( test )
	
		:waitFor( function()
		
			return LrmDevelopModel.requestBinaryP( catalog, assetId, binaryPreference, developInfo )
			
		end )
		
		:continueWhenValueMatches( 'data', kProxyPath, false )
	
end

--------------------------------------------------------------------------------
function LrmDevelopModelTest.testRequestProxyAvailable(test)

	local assetId = KSIdGenerator.uuidInLowercaseHex()

	local developInfo = {
		hasMaster = false,
		originalPath = nil,
		hasProxy = true,
		proxyPath = kProxyPath,
	}

	local binaryPreference = LrmConfig.StrategyProxy

	WFAsyncTestCase(test)

		:waitFor(function()

			return LrmDevelopModel.requestBinaryP(catalog, assetId, binaryPreference, developInfo)

		end)

		:continueWhenValueMatches('data', kProxyPath, false)

end

--------------------------------------------------------------------------------
function LrmDevelopModelTest.testRequestProxyNotAvailable(test)

	local assetId = KSIdGenerator.uuidInLowercaseHex()

	local developInfo = {
		hasMaster = true,
		originalPath = kOriginalPath,
		hasProxy = false,
		proxyPath = nil,
	}

	local binaryPreference = LrmConfig.StrategyProxy

	WFAsyncTestCase(test)

		:waitFor(function()

			return LrmDevelopModel.requestBinaryP(catalog, assetId, binaryPreference, developInfo)

		end)

		:continueWhenValueMatches('error', 'No proxy available on Oz')

end

--------------------------------------------------------------------------------
function LrmDevelopModelTest.testRequestMasterAvailable(test)

	local assetId = KSIdGenerator.uuidInLowercaseHex()

	local developInfo = {
		hasMaster = true,
		originalPath = kOriginalPath,
		hasProxy = false,
		proxyPath = nil,
	}

	local binaryPreference = LrmConfig.StrategyMaster

	WFAsyncTestCase(test)

		:waitFor(function()

			return LrmDevelopModel.requestBinaryP(catalog, assetId, binaryPreference, developInfo)

		end)

		:continueWhenValueMatches('data', kOriginalPath, true)

end

--------------------------------------------------------------------------------
function LrmDevelopModelTest.testRequestMasterNotAvailable(test)

	local assetId = KSIdGenerator.uuidInLowercaseHex()

	local developInfo = {
		hasMaster = false,
		originalPath = nil,
		hasProxy = true,
		proxyPath = kProxyPath,
	}

	local binaryPreference = LrmConfig.StrategyMaster

	WFAsyncTestCase(test)

		:waitFor(function()

			return LrmDevelopModel.requestBinaryP(catalog, assetId, binaryPreference, developInfo)

		end)

		:continueWhenValueMatches('error', 'No master available on Oz')

end

--------------------------------------------------------------------------------
function LrmDevelopModelTest.testRequestProxyBothNotAvailable(test)

	local assetId = KSIdGenerator.uuidInLowercaseHex()

	local developInfo = {
		hasMaster = false,
		originalPath = nil,
		hasProxy = false,
		proxyPath = nil,
	}

	local binaryPreference = LrmConfig.StrategyProxy

	WFAsyncTestCase(test)

		:waitFor(function()

			return LrmDevelopModel.requestBinaryP(catalog, assetId, binaryPreference, developInfo)

		end)

		:continueWhenValueMatches('error', 'No proxy and master available on Oz')

end

--------------------------------------------------------------------------------
function LrmDevelopModelTest.testRequestMasterBothNotAvailable(test)

	local assetId = KSIdGenerator.uuidInLowercaseHex()

	local developInfo = {
		hasMaster = false,
		originalPath = nil,
		hasProxy = false,
		proxyPath = nil,
	}

	local binaryPreference = LrmConfig.StrategyMaster

	WFAsyncTestCase(test)

		:waitFor(function()

			return LrmDevelopModel.requestBinaryP(catalog, assetId, binaryPreference, developInfo)

		end)

		:continueWhenValueMatches('error', 'No proxy and master available on Oz')

end

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

function LrmDevelopModelTest.testBootVersionCreation_owner( test )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	WFAsyncTestCase( test, TEST_TIMEOUT )
	
		:waitFor( function()
			
			return createAsset( assetId )
		end )
		
		:waitFor( function()
		
			return LrmDevelopModel.createBootVersionIfNeeded( mockCatalog, assetId )
				
				:flatMapLatest( function( versionId )
					-- Make sure we are receiving a valid version id.
					
					return mockCatalog:indexStore()
						:queryOnce( {
							sql = "SELECT * FROM versions where docId = ?",
							quiesceUntilUpToDate = true,
							singleColumnQuery = true,
							versionId
						})
				end )
				:map( function( row )
					return row and #row == 1
				end )
				:call( asKSPromise )

		end )
		
		:continueWhenValueMatches( 'data', true )
		
		:waitFor( function()
		
			return LrmDevelopModel.createBootVersionIfNeeded( mockCatalog, assetId )
				:call( asKSPromise )

		end )

		:continueWhenValueMatches( 'data', nil )
		
end

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

function LrmDevelopModelTest.testBootVersionCreation_editor( test )
		
	-- Shouldn't create boot versions for editor, who is not the contributor
	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	WFAsyncTestCase( test, TEST_TIMEOUT )
	
		:waitFor( function()
			
			return createAsset( assetId, true )
		end )
		
		:waitFor( function()
		
			return LrmDevelopModel.createBootVersionIfNeeded( mockCatalog, assetId )
				:call( asKSPromise )

		end )

		:continueWhenValueMatches( 'data', nil )
		
end

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

function LrmDevelopModelTest.testBootVersionCreation_contributer( test )

	-- Should create boot version for contributors
	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	WFAsyncTestCase( test, TEST_TIMEOUT )
	
		:waitFor( function()
			
			return createAsset( assetId, true, true )
		end )
		
		:waitFor( function()
		
			return LrmDevelopModel.createBootVersionIfNeeded( mockCatalog, assetId )
				:call( asKSPromise )

		end )

		:continueWhenValueMatches( 'data', nil )
		
end

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


return LrmDevelopModelTest
