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

WFRxHttpServerTest.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2019 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 KSData = require "KSData"
local KSPathUtils = require "KSPathUtils"
local KSIdGenerator = require "KSIdGenerator"

local WFCatUser = require "WFCatUser"
local WFCatSpec = require "WFCatSpec"
local WFCatalog = require "WFCatalog"

local OzCatalogUrls = require "OzCatalogUrls"

local WFRxTestCase = require "WFRxTestCase"
local WFRxHttpClient = require "WFRxHttpClient"
local WFRxHttpServer = require "WFRxHttpServer"


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

local WFRxHttpServerTest = {}

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

local catalog

local httpServer

local TIME_LIMIT = 10

local serverBaseUrl = OzCatalogUrls.baseServerUrl

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

local function serverAddress( path )

	local ports = httpServer:getPorts()
	
	return string.format( 'http://127.0.0.1:%d%s', ports[ 1 ], path or '/' )

end

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

function WFRxHttpServerTest.setUp(  )
	
	local docStorePath = ':memory:'
	local userId = KSIdGenerator.uuidInLowercaseHex()
	local catalogId = KSIdGenerator.uuidInLowercaseHex()
	local rootCatalogPath = KSPathUtils.getStandardFilePath 'temp'
	
	local catalogOptions = {
		indexSpecScript = 'WFCatIndexDefinitions.lua',
		setupConflictResolver = false,
		docStorePath = docStorePath,
		noFileAccessDb = true,
	}
	
	local user = WFCatUser( serverBaseUrl, userId, ':memory:' )
	
	local catSpec = WFCatSpec( user, catalogId )
	catalog = WFCatalog( catSpec, rootCatalogPath, catalogOptions )

	local serverOptions = {
		listening_ports = '0'
	}

	httpServer = WFRxHttpServer.start( 'WFRxHttpServerTestHandlers.startRequest', serverOptions, catalog )

end

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

function WFRxHttpServerTest.tearDown(  )

	if httpServer then

		httpServer:close()
		httpServer = nil
	
	end
	
	if catalog then
	
		catalog:close()
		catalog = nil
		
	end

end

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

function WFRxHttpServerTest.rxTestSimpleGet( rxTest )

	rxTest:setTimeLimit( TIME_LIMIT )

	rxTest:expectSingleValue( 
		WFRxHttpClient.get( serverAddress() )
			:map( function( data, headers )
				return tostring( data ), headers.status_code
			end ),
		'Hello, Wichita!\n', '200' )

	-- Unfortunately, WFRxHttpClient does not give us access to the error message

	-- provoke a 404
	rxTest:expectOnlyError( 
		WFRxHttpClient.get( serverAddress('/does_not_exist') )
			:tap( nil, function( data, headers )
				rxTest:expectEqual( 'userdata', type(data) )
				-- WFRx
				-- rxTest:expectEqual( 'silly path, mate', tostring( data ) )
				rxTest:expectEqual( 'table', type(headers) )
				rxTest:expectEqual( '404', headers.status_code )
			end ),
		':ignore:', ':ignore:', ':ignore:' )


	-- provoke a 404
	rxTest:expectOnlyError( 
		WFRxHttpClient.get( serverAddress('/error') )
			:tap( nil, function( data, headers )
				rxTest:expectEqual( 'userdata', type(data) )
				-- rxTest:expectEqual( 'the server threw a boo', tostring( data ) )
				rxTest:expectEqual( 'table', type(headers) )
				rxTest:expectEqual( '404', headers.status_code )
			end ),
		':ignore:', ':ignore:', ':ignore:' )

end


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

function WFRxHttpServerTest.rxTestDispatch( rxTest )

	rxTest:setTimeLimit( TIME_LIMIT )

	rxTest:expectSingleValue( 
		WFRxHttpClient.get( serverAddress( '/foo/7' ) )
			:map( function( data, headers )
			
				return tostring( data ), headers.status_code
			
			end ),
		'foo7', '200' )

	-- now provoke a 404
	rxTest:expectOnlyError( 
		WFRxHttpClient.get( serverAddress( '/foo/bar' ) )
			:tap( nil, function( data, headers )
				rxTest:expectEqual( 'userdata', type(data) )
				rxTest:expectEqual( 'table', type(headers) )
				rxTest:expectEqual( '404', headers.status_code )
			end ),
		':ignore:', ':ignore:', ':ignore:' )

end

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

function WFRxHttpServerTest.rxTestPut( rxTest )

	rxTest:setTimeLimit( TIME_LIMIT )

	rxTest:expectSingleValue( 
		WFRxHttpClient.put( serverAddress( '/put' ), 'PutIt!' )
			:map( function( data, headers )
			
				return tostring( data ), headers.status_code
			
			end ),
		'PutIt!', '200' )

	-- now provoke a 404
	rxTest:expectOnlyError( 
		WFRxHttpClient.put( serverAddress( '/' ), 'PutIt!' )
			:tap( nil, function( data, headers )
				rxTest:expectEqual( 'userdata', type(data) )
				rxTest:expectEqual( 'table', type(headers) )
				rxTest:expectEqual( '404', headers.status_code )
			end ),
		':ignore:', ':ignore:', ':ignore:' )

end


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

function WFRxHttpServerTest.rxTestDocStore( rxTest )
	
	rxTest:setTimeLimit( TIME_LIMIT )

	local docId = KSIdGenerator.uuidInLowercaseHex()

	rxTest:expectSingleValue( catalog:docStore():applyOverlay {
		_id = docId,
		type = 'testDoc',
		content = 'Hello Wichita!\n'
	}, ':ignore:' )

	rxTest:expectSingleValue( 
		WFRxHttpClient.get( serverAddress( '/docValue/' .. docId ) )
			:map( function( data, headers )
				return tostring( data )
			end ),
		'Hello Wichita!\n' )
	
end

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

function WFRxHttpServerTest.rxTestSendFile( rxTest )
	
	rxTest:setTimeLimit( TIME_LIMIT )

	rxTest:expectSingleValue( 
		WFRxHttpClient.get( serverAddress( '/sendFile/1.5MB.jpg' ) )
			:map( function( data, headers )
				local d = KSData.make( data )
				local md5 = d:digest( 'MD5' )
				return md5
			end ),
		'42d011e733b3bd8512e28243be45a67c' )
	
		-- now provoke a 404
	rxTest:expectOnlyError( 
		WFRxHttpClient.get( serverAddress( '/sendFile/foo' ) )
			:tap( nil, function( data, headers )
				rxTest:expectEqual( 'userdata', type(data) )
				rxTest:expectEqual( 'table', type(headers) )
				rxTest:expectEqual( '404', headers.status_code )
			end ),
		':ignore:', ':ignore:', ':ignore:' )

end


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

return WFRxTestCase.wrapSuite( WFRxHttpServerTest )
