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

WFHttpClient.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2011 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.rxlua
local WFRxPromiseBridge = require 'WFRxPromiseBridge'

	-- WF.web.http_client
local WFRxHttpClient = require 'WFRxHttpClient'


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

local asKSPromise = WFRxPromiseBridge


--============================================================================--
--[[!
	\class WFHttpClient
	\brief This namespace provides basic HTTP services.
]]--

-- @mark WFHttpClient namespace

local WFHttpClient = {
	responseMatchesContentType = WFRxHttpClient.responseMatchesContentType,
	responseContentTypeIsJson = WFRxHttpClient.responseContentTypeIsJson,
}

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

--[[!
	\brief Starts an HTTP GET request and returns the response via a promise.

	\param url (string) The URL to fetch.
	\param options (optional, table) Options to modify the request.
	\param sequencing (optional, string) A string specifying the sequencing model
			Valid values include 'LIFO' and 'FIFO'. Defaults to FIFO if it doesn't
			find a match.

	\return <code>P< data, headers ></code> A Promise that resolves to the response from HTTP server.

	\b Usage:
\code
local options = {
    requestHeaders = {                  -- optional
        { header = 'Content-Type', value = 'application/json' },
        { header = 'Accept', value = 'application/json' },
    }
    requestMethod = 'GET',              -- optional
                -- (must be a valid HTTP request method)
    returnHttpErrorsAsData = true,      -- optional
    timeout = (# seconds),              -- optional
	manuallyManageCookies = false,		-- optional
	followRedirects = true,				-- optional
	sendProgress = true,				-- optional
}

local urlDataP = WFHttpClient.getP( url, options, sequencing )
    :whenResolvedDo( function( status, data, headers )

        if status == 'data' then

            -- The promise resolves as "data" in the "normal" case of a
            -- valid HTTP response with a non-error (<400) HTTP status code.
            -- The promise also resolves to "data" if the server returns
            -- an HTTP error code when returnHttpErrorsAsData = true.

            -- The data in this case is a KSData with the complete response body.
	    -- and 'header' is  a Lua table of key/value pairs.
            -- A special key 'status_code' in the table contains a string
            -- with the HTTP response code (such as "200").

            -- The default HTTP request method is GET, but you can override this
            -- with options.requestMethod.

        elseif status == 'error' then

            -- The promise resolves with "error" status if the system does
            -- not receive a valid HTTP response (for example, if the connection
            -- was refused or timed out). In this case, the data argument is a string
            -- describing the error and headers are nil.

            -- The promise also resolves with "error" if a valid HTTP response
            -- is received but the HTTP status code indicates an error (>= 400).
            -- You can override this behavior with returnHttpErrorsAsData = true.
 
            -- If an HTTP error response is signaled via "error" status, then
            -- data and headers are KSData and table as in the "data" case.

        end )
\endcode

	This returns a standard promise. You are responsible for managing the lifetime
	of the promise via the action(s) you attach to it. The HTTP request is
	canceled if all of its promise actions are closed.

	NOTE: This function does no caching. Calling this function, always
	creates network traffic.
--]]

function WFHttpClient.getP( url, options, sequencing )

	return WFRxHttpClient.get( url, options, sequencing )
		:call( asKSPromise )
	
end

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

--[[!
	\brief Starts an HTTP PUT request and returns the response via a promise.

	\param url (string) the URL to fetch
	\param data (\c KSData or string) data to send with the request.  Note, a string may be
	interpreted as a file path if the dataFormat option is set to "filePath"
	\param options (optional, table) options to modify the request

	\return <code>P< data, headers ></code> A Promise that resolves to the response from HTTP server

	For now, this only supports URL encoding. Could easily be adapted for MIME
	encoding as well, but this hasn't proven necessary as yet.

	\b Usage:
\code
local options = {
    requestHeaders = {
        { header = 'Content-Type', value = 'application/json' },
        { header = 'Accept', value = 'application/json' },
    }
    requestMethod = 'PUT',              -- optional
                -- (must be a valid HTTP request method)
    timeout = (# seconds),              -- optional
    returnHttpErrorsAsData = true,      -- optional
	manuallyManageCookies = false,		-- optional
	followRedirects = true,				-- optional
	sendProgress = true,				-- optional
	dataFormat = "data|filePath",
		-- optional, specify filePath to interpret data as a file path
		-- NOTE: caller must ensure file exists until the result resolves
		-- default value, "data" interprets data as bytes to send
	offset = 123, -- optional, start the upload from this byte offset
	length = 234, -- optional, only send this many bytes
}

local urlDataP = WFHttpClient.putP( url, data, options )
    :whenResolvedDo( function( status, data, headers )

        if status == 'data' then

            -- The promise resolves as "data" in the "normal" case of a
            -- valid HTTP response with a non-error (<400) HTTP status code.
            -- The promise also resolves to "data" if the server returns
            -- an HTTP error code when returnHttpErrorsAsData = true.

            -- The data in this case is a KSData with the complete response body.
	    -- and 'header' is  a Lua table of key/value pairs.
            -- A special key 'status_code' in the table contains a string
            -- with the HTTP response code (such as "200").

            -- The default HTTP request method is PUT, but you can override this
            -- with options.requestMethod.

        elseif status == 'error' then

            -- The promise will resolve with "error" status if the system does
            -- not receive a valid HTTP response (i.e. connection refused,
            -- timeout, etc.). In this case, the data argument will be a string
            -- describing the error and headers will be nil.

            -- The promise resolves with "error" status if the system does
            -- not receive a valid HTTP response (for example, if the connection
            -- was refused or timed out). In this case, the data argument is a string
            -- describing the error and headers are nil.

            -- The promise also resolves with "error" if a valid HTTP response
            -- is received but the HTTP status code indicates an error (>= 400).
            -- You can override this behavior with returnHttpErrorsAsData = true.
 
            -- If an HTTP error response is signaled via "error" status, then
            -- data and headers are KSData and table as in the "data" case.

        end )
\endcode
			
	This returns a standard promise. You are responsible for managing the lifetime
	of the promise via the action(s) you attach to it. The HTTP request is
	canceled if all of its promise actions are closed.

--]]

function WFHttpClient.putP( url, data, options )
	
	return WFRxHttpClient.put( url, data, options )
		:call( asKSPromise )

end

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

function WFHttpClient.setProxyCredentialsP( user, password )

	return WFRxHttpClient.setProxyCredentials( user, password )
		:call( asKSPromise )

end

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

return WFHttpClient
