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

PixelProviderLocalBinaryPathCheckTaskTest.lua

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

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

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

local Rx = require 'Rx'
local Observable = Rx.Observable

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

	-- WF.core.utils
local KSIdGenerator = require 'KSIdGenerator'
local KSTableUtils = require 'KSTableUtils'
local WFFileUtils = require 'WFFileUtils'
local KSData = require 'KSData'
local WFCrypto = require 'WFCrypto'

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

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

local KSTableUtils_derefOpt = assert( KSTableUtils.derefOpt, 
										"KSTableUtils.derefOpt undefined" )

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

local PixelProviderLocalBinaryPathCheckTaskTest = {}

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

local function basicDocValue( binaryType, fileName, captureDate, sha256 )

	return {

		type = 'asset',
		subtype = 'image',
		
		captureDate = captureDate,
		
		importSource = {
			importTimestamp = "2015-05-26T17:34:23-07:00",
			fileName = fileName,
			sha256 = sha256,
		},

		_serverProvidedMetadata = {
			revision_ids = {
				KSIdGenerator.uuidInLowercaseHex()
			},
			links = {
			
				[ '/rels/master' ] = {
					href = 'path/to/original.jpg',
				},
				[ '/rels/proxy_type/2560' ] = {
					href = 'path/to/proxy.jpg',
				}
			}
		}

	}
	
end

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

local function createAsset( rxTest, wfCatalog, binaryType, createLocalOriginal, forceFakeSha256 )

	local docId = KSIdGenerator.uuidInLowercaseHex()
	
	local fileName = KSIdGenerator.uuidInLowercaseHex()
	
	local captureDate = "2015-05-26T17:34:23-07:00"
	
	local filePath = wfCatalog:fileSpec():pathForOriginal( fileName, captureDate )
	
	local sha256 = KSIdGenerator.uuidInLowercaseHex()

	if createLocalOriginal then
		local mockImage = KSData.make( fileName )
		KSData.saveToFile( mockImage, filePath )	
		sha256 = forceFakeSha256 and sha256 or WFCrypto.digestFile( filePath, 'SHA256' )
	end
	
	local docValue = basicDocValue( binaryType, fileName, captureDate, sha256 )
	docValue._id = docId
	
	rxTest:expectSingleValue( wfCatalog:docStore():setDocValue( docValue ), ':ignore:' )
	
	local localId
	
	rxTest:expectSingleValue(
		wfCatalog:docStore():docValue( docId )
			:map( function( docValue )
			
				localId = docValue._localId
				return true
				
			end ), true )
			

	return localId, filePath, sha256

end

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

local function checkStandardAnnotations( rxTest, docStore, localId, shouldExist, expectedSha )

	rxTest:expectSingleValue(
		docStore:docValue( localId )
			:map( function( docValue )
			
				local localOnlyFiles = KSTableUtils_derefOpt( docValue, '_localOnly', 'files' )
				local volumeGuid = KSTableUtils_derefOpt( localOnlyFiles, 'original', 'master', 'volumeGuid' )
				local relativePath = KSTableUtils_derefOpt( localOnlyFiles, 'original', 'master', 'relativePath' )
				local sha256 = KSTableUtils_derefOpt( localOnlyFiles, 'original', 'master', 'sha256' )
			
				return {
					not not volumeGuid,
					not not relativePath,
					expectedSha and sha256 or ( not not sha256 ),
				}
				
			end ), { shouldExist, shouldExist, expectedSha or shouldExist } )

end

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

function PixelProviderLocalBinaryPathCheckTaskTest.rxTestCheckExpectedPathForOriginal( rxTest )

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest )
	local docStore = wfCatalog:docStore()
	local checkTask = PixelProviderLocalBinaryPathCheckTask
	local fileSpec = wfCatalog:fileSpec()
	
	local mockCacheChecker = {
	
		checkPath = function( _, path )
			return Observable.just( WFFileUtils.exists( path ) )
		end
		
	}
	
	-- No untracked local original
	
	local localId, filePath = createAsset( rxTest, wfCatalog, 'original', false )
	
	checkStandardAnnotations( rxTest, docStore, localId, false )
	
	rxTest:expectSingleValue( checkTask.checkExpectedPathForOriginal( docStore, mockCacheChecker, fileSpec, localId ), false )
	
	checkStandardAnnotations( rxTest, docStore, localId, false )
	
	-- Untracked local original exists
	
	local localId_2, filePath_2, sha256_2 = createAsset( rxTest, wfCatalog, 'original', true )
	
	checkStandardAnnotations( rxTest, docStore, localId_2, false )
	
	rxTest:expectSingleValue( checkTask.checkExpectedPathForOriginal( docStore, mockCacheChecker, fileSpec, localId_2 ), filePath_2 )
	
	checkStandardAnnotations( rxTest, docStore, localId_2, true, sha256_2 )
	
	-- Untracked local original exists but has a different SHA
	
	local localId_3, filePath_3 = createAsset( rxTest, wfCatalog, 'original', true, true )
	
	checkStandardAnnotations( rxTest, docStore, localId_3, false )
	
	rxTest:expectSingleValue( checkTask.checkExpectedPathForOriginal( docStore, mockCacheChecker, fileSpec, localId_3 ), false )
	
	checkStandardAnnotations( rxTest, docStore, localId_3, false )
	
	-- Cleanup
	
	rxTest:finally( function()
	
		if filePath then
			WFFileUtils.delete( filePath )
		end
		
		if filePath_2 then
			WFFileUtils.delete( filePath_2 )
		end
	
		if filePath_3 then
			WFFileUtils.delete( filePath_3 )
		end
	
	end )

end

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

return WFRxTestCase.wrapSuite( PixelProviderLocalBinaryPathCheckTaskTest )
