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

ADOBE CONFIDENTIAL
------------------
Copyright 2023 Adobe
All Rights Reserved.

NOTICE: All information contained herein is, and remains
the property of Adobe and its suppliers, if any. The intellectual
and technical concepts contained herein are proprietary to Adobe
and its suppliers and are protected by all applicable intellectual
property laws, including trade secret and copyright laws.
Dissemination of this information or reproduction of this material
is strictly forbidden unless prior written permission is obtained
from Adobe.

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

	-- WF.core
local KSStringUtils = require 'KSStringUtils'
local WFCapabilities = require 'WFCapabilities'
local WFPlatformInfo = require 'WFPlatformInfo'

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

local function normalizeAppNumber( appNumber )

	-- Ensure the appNumber starts with two numbers, separated by a dot
	-- This is required for Oz to recognize us.

	if not string.find( appNumber, "^%d+%.%d+%." ) then
		appNumber = string.gsub( appNumber, "^%d+%.%d+", "%0.0" )
	end

	if not string.find( appNumber, "^%d+%.%d+%." ) then
		appNumber = string.gsub( appNumber, "^%d+", "%0.0.0" )
	end

	if not string.find( appNumber, "^%d+%.%d+%." ) then
		appNumber = "0.0." .. appNumber
	end

	return appNumber

end

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

--[[!
	\brief Splits a multipart response using the provided boundary.

	\param multipartResponse (string) The multipart response from the request.
	\param boundary (string) Multipart boundary, including the "--" prefix.

	\return (table) A table of parts. Further post processing is needed to extract
		the part headers and part data. See parseMultipartResponse in WFRxHttpClientImp.
]]--

local function splitMultipartResponseAtBoundary( multipartResponse, boundary )

	-- According to RFC 2046, section 5.1.1:
	--
	-- boundary := 0*69<bchars> bcharsnospace
	--
	-- bchars := bcharsnospace / " "
	--
	-- bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" /
	--     "+" / "_" / "," / "-" / "." /
	--     "/" / ":" / "=" / "?"

	-- In order to split the multipart response successful, we must first escape
	-- the magic lua characters (  ( ) . % + - * ? [ ^ $ ), which may be a part
	-- of the boundary: ( ) . + - ?

	local escapedBoundary = boundary:gsub( "([^%w])", "%%%1" )
		-- You can use the escape "%" not only for the magic characters, but also
		-- for all other non-alphanumeric characters. This is a simple way to escape
		-- all non-alphanumeric characters.

	local parts = KSStringUtils.split( multipartResponse, escapedBoundary ) or {}

	return parts

end

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

local function optFn( itemName, default )

	local appBuildNum = WFCapabilities.getCapability( 'WFHttpClient_' .. itemName )

	if not appBuildNum then

		local fn = WFPlatformInfo[ 'get' .. itemName ]

		appBuildNum = fn and fn()

		if not appBuildNum then
			appBuildNum = default
		end

	end

	return appBuildNum

end

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

local function getUserAgent()

	-- Configure default user agent.
	-- Clients other than Revel will need to add their appIdentifier
	-- to the case below if they want a custom user agent name.

	local appNumber

	if WFPlatformInfo.isAndroid then

		appNumber = optFn( 'AppVersion' )

		if not appNumber then
			appNumber = optFn( 'AppVersion', "0.0" ) .. ".Dev"
		end

	else

		local version = optFn( 'AppVersion', '0.0' )
		local build = optFn( 'Build', 'Dev' )

		appNumber = string.format( "%s.%s", version, build )

	end

	appNumber = normalizeAppNumber( appNumber )

	local baseName = optFn( 'UserAgentAppName' )
			or optFn( 'AppName', 'Wichita Foundation Client' )

	local manufacturer = optFn( 'DeviceManufacturer', 'Unknown' )
	local model = optFn( 'DeviceModel', 'Unknown' )

	local mapWFPlatformOSToUserAgentOS = {
		[ "MacOSX" ] = "OSX",
		[ "Windows 7" ] = "Windows",
	}

	local operatingSystem = WFPlatformInfo.getOS()
	operatingSystem = operatingSystem and mapWFPlatformOSToUserAgentOS[ operatingSystem ] or operatingSystem

	local osVer = optFn( 'OSVersion', "?.?.?" )

	local sUserAgent = string.format(
			"%s(%s;%s;%s;%s;%s)",
			baseName,
			appNumber,
			manufacturer,
			model,
			operatingSystem,
			osVer )

	return sUserAgent

end

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

return {
	getUserAgent = getUserAgent,
	normalizeAppNumber = normalizeAppNumber,
	splitMultipartResponseAtBoundary = splitMultipartResponseAtBoundary
}
