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

WFCatBinaryDownloaderTest.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.lua
local KSData = require 'KSData'

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

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

local WFRxHttpClient = require 'WFRxHttpClient'

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

local kUserId = '87f526b44f9e41eca6cb5a550f84ceb6'
	-- Helpful bash one-liner. Put a new uuid on the clipboard (mac cmdline):
	-- uuidgen	| perl -p -e 's/-//g;s/[A-Z]/lc($&)/ge;' | pbcopy

local priority = WFRxHttpClient.requestPriorityMedium
local cost = WFRxHttpClient.requestCostDefault

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

local WFCatBinaryDownloaderTest = {}

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

local function mapKSDataToString( maybeKSData )

	if not KSData.isData( maybeKSData ) then
		return string.format( "Expected KSData, got %s instead", type( maybeKSData ) ),
			   maybeKSData
	else
		return tostring( maybeKSData )
	end

end


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

local function makeSuccessfulResponseHeaders( response )

	return {
		status_code = '200',
		[ 'Content-Length' ] = KSData.length( response ),
	}

end

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

local function makeUrlResponse( url, responseString, maybeCost )

	local response = KSData.make( responseString )

	return {
		url = url,
		response = response,
		headers = makeSuccessfulResponseHeaders( response ),
		options = {
			requestCost = maybeCost or cost,
			requestPriority = priority
		}
	}

end

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

function WFCatBinaryDownloaderTest.rxTestGetRendition( rxTest )

	local catalogSpec = WFCatSpecMock( '98db98bfd554470dab2f862a4b853c40', kUserId, rxTest,

		{
			makeUrlResponse( "/v2/catalogs/blah/blah/blah/t2x", 
				"pseudo-jpeg-thumbnail2x", 
				WFRxHttpClient.requestCostDownloadRendition ),
		} )
	
	local catalog = WFCatMockCatalog.createWFCatalogForTestWithSpec( rxTest, catalogSpec )

	local downloader = WFCatBinaryDownloader( catalog )

	rxTest:expectSingleValue(

		catalog:docStore():setDocValue {
			_id = '6f607906eefa4e9fb80da8fde2805c11',
			_serverProvidedMetadata = {
				links = {
					[ '/rels/rendition_type/thumbnail2x' ] = {
						href = '/v2/catalogs/blah/blah/blah/t2x',
					},
				},
			},
		},

		':ignore:' )

	rxTest:expectSingleValue(

		downloader:getRendition( '6f607906eefa4e9fb80da8fde2805c11', 'thumbnail2x', priority )
			:map( mapKSDataToString ),

		'pseudo-jpeg-thumbnail2x' )

end

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

function WFCatBinaryDownloaderTest.rxTestGetRendition_errorUrlNotAvailable( rxTest )

	local catalogSpec = WFCatSpecMock( '98db98bfd554470dab2f862a4b853c40', kUserId, rxTest,

		{
		} )

	local catalog = WFCatMockCatalog.createWFCatalogForTestWithSpec( rxTest, catalogSpec )

	local downloader = WFCatBinaryDownloader( catalog )

	rxTest:expectSingleValue(

		catalog:docStore():setDocValue {
			_id = '6f607906eefa4e9fb80da8fde2805c11',
			_serverProvidedMetadata = {
				links = {
					[ '/rels/rendition_type/not-thumbnail2x' ] = {
						href = '/v2/catalogs/blah/blah/blah/t2x',
					},
				},
			},
		},

		':ignore:' )

	rxTest:expectOnlyError(

		downloader:getRendition( '6f607906eefa4e9fb80da8fde2805c11', 'thumbnail2x', priority )
			:map( mapKSDataToString ),

		"No URL provided by Oz for asset ID 6f607906eefa4e9fb80da8fde2805c11 link /rels/rendition_type/thumbnail2x", 
		':ignore:', ':ignore:', ':ignore:', ':ignore:' )

end

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

function WFCatBinaryDownloaderTest.rxTestGetRendition_errorHttpFail( rxTest )

	local catalogSpec = WFCatSpecMock( '98db98bfd554470dab2f862a4b853c40', kUserId, rxTest,

		{
			{
				url = "/v2/catalogs/blah/blah/blah/t2x",
				fail = {
					"Not found",
					headers = {
						status_code = '404',
					},
				},
				options = {
					requestCost = WFRxHttpClient.requestCostDownloadRendition,
					requestPriority = priority
				}
			},
		} )

	local catalog = WFCatMockCatalog.createWFCatalogForTestWithSpec( rxTest, catalogSpec )

	local downloader = WFCatBinaryDownloader( catalog )

	rxTest:expectSingleValue(

		catalog:docStore():setDocValue {
			_id = '6f607906eefa4e9fb80da8fde2805c11',
			_serverProvidedMetadata = {
				links = {
					[ '/rels/rendition_type/thumbnail2x' ] = {
						href = '/v2/catalogs/blah/blah/blah/t2x',
					},
				},
			},
		},

		':ignore:' )

	rxTest:expectOnlyError(
		downloader:getRendition( '6f607906eefa4e9fb80da8fde2805c11', 'thumbnail2x', priority ),
		"Not found", ':ignore:', '/rels/rendition_type/thumbnail2x', '/v2/catalogs/blah/blah/blah/t2x', ':ignore:' )

end

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

function WFCatBinaryDownloaderTest.rxTestGetProxy( rxTest )

	local catalogSpec = WFCatSpecMock( '98db98bfd554470dab2f862a4b853c40', kUserId, rxTest,

		{
			makeUrlResponse( "/v2/catalogs/blah/blah/proxy/blah/blah", "pseudo-dng-proxy-2560" ),
		} )

	local catalog = WFCatMockCatalog.createWFCatalogForTestWithSpec( rxTest, catalogSpec )

	local downloader = WFCatBinaryDownloader( catalog )

	rxTest:expectSingleValue(

		catalog:docStore():setDocValue {
			_id = '6f607906eefa4e9fb80da8fde2805c11',
			_serverProvidedMetadata = {
				links = {
					[ '/rels/proxy_type/2560' ] = {
						href = '/v2/catalogs/blah/blah/proxy/blah/blah',
					},
				},
			},
		},

		':ignore:' )

	rxTest:expectSingleValue(

		downloader:getProxy( '6f607906eefa4e9fb80da8fde2805c11', '2560', priority )
			:map( mapKSDataToString ),

		'pseudo-dng-proxy-2560' )

end

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

function WFCatBinaryDownloaderTest.rxTestGetMaster( rxTest )

	local catalogSpec = WFCatSpecMock( '98db98bfd554470dab2f862a4b853c40', kUserId, rxTest,

		{
			makeUrlResponse( "/v2/catalogs/blah/blah/master", "pseudo-master" ),
		} )

	local catalog = WFCatMockCatalog.createWFCatalogForTestWithSpec( rxTest, catalogSpec )

	local downloader = WFCatBinaryDownloader( catalog )

	rxTest:expectSingleValue(

		catalog:docStore():setDocValue {
			_id = '6f607906eefa4e9fb80da8fde2805c11',
			_serverProvidedMetadata = {
				links = {
					[ '/rels/master' ] = {
						href = '/v2/catalogs/blah/blah/master',
					},
				},
			},
		},

		':ignore:' )

	rxTest:expectSingleValue(

		downloader:getMaster( '6f607906eefa4e9fb80da8fde2805c11', priority )
			:map( mapKSDataToString ),

		'pseudo-master' )

end

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

function WFCatBinaryDownloaderTest.rxTestGetMasterWithContentLengthFailure( rxTest )

	local failedResponse = makeUrlResponse( "/v2/catalogs/blah/blah/master", "pseudo-master" )
	failedResponse.headers[ 'Content-Length' ] = failedResponse.headers[ 'Content-Length' ] + 1
		-- pretend like there is suppose to be one more byte in the file to force a failure

	local catalogSpec = WFCatSpecMock( '98db98bfd554470dab2f862a4b853c40', kUserId, rxTest,

		{
			failedResponse,
			makeUrlResponse( "/v2/catalogs/blah/blah/master", "pseudo-master" ),
		} )


	local catalog = WFCatMockCatalog.createWFCatalogForTestWithSpec( rxTest, catalogSpec )

	local downloader = WFCatBinaryDownloader( catalog )

	rxTest:expectSingleValue(

		catalog:docStore():setDocValue {
			_id = '6f607906eefa4e9fb80da8fde2805c11',
			_serverProvidedMetadata = {
				links = {
					[ '/rels/master' ] = {
						href = '/v2/catalogs/blah/blah/master',
					},
				},
			},
		},

		':ignore:' )

	rxTest:expectOnlyError(
		downloader:getMaster( '6f607906eefa4e9fb80da8fde2805c11', priority ),

		"Error downloading file, dataLength doesn't match headers.Content-Length",
		':ignore:',
		'/rels/master',
		'/v2/catalogs/blah/blah/master',
		':ignore:' )

	rxTest:expectSingleValue(

		downloader:getMaster( '6f607906eefa4e9fb80da8fde2805c11' )
			:map( mapKSDataToString ),

		'pseudo-master' )

end

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

function WFCatBinaryDownloaderTest.rxTestGetXmp( rxTest )

	local catalogSpec = WFCatSpecMock( '98db98bfd554470dab2f862a4b853c40', kUserId, rxTest,

		{
			makeUrlResponse( "/v2/catalogs/blah/blah/xmp", "not-really-valid-xmp" ),
		} )
		
	local catalog = WFCatMockCatalog.createWFCatalogForTestWithSpec( rxTest, catalogSpec )

	local downloader = WFCatBinaryDownloader( catalog )

	rxTest:expectSingleValue(

		catalog:docStore():setDocValue {
			_id = '6f607906eefa4e9fb80da8fde2805c11',
			_serverProvidedMetadata = {
				links = {
					[ '/rels/xmp' ] = {
						href = '/v2/catalogs/blah/blah/xmp',
					},
				},
			},
		},

		':ignore:' )

	rxTest:expectSingleValue(

		downloader:getXmp( '6f607906eefa4e9fb80da8fde2805c11' )
			:map( mapKSDataToString ),

		'not-really-valid-xmp' )

end

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

return WFRxTestCase.wrapSuite( WFCatBinaryDownloaderTest )
