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

NmbProxyAuthErrorMonitor.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2018 Adobe Systems Incorporated
All Rights Reserved.

NOTICE: All information contained herein is, and remains 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 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 Systems Incorporated.

----------------------------------------------------------------------------]]--
	-- Rx
local WFRxScheduler = require "WFRxScheduler"

	-- WF.oz_client.managed_catalog
local WFRxHttpClient = require 'WFRxHttpClient'

local WFLogger = require 'WFLogger'

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

local logger = WFLogger( 'NmbProxyAuthMonitor' )

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

-- @mark NmbProxyAuthMonitor namespace

local NmbProxyAuthErrorMonitor = {}

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

local function checkOptTypeWithWarn( varName, var, expectedType )

	if var == nil then 
	
		return false 
		
	end

	if type( var ) == expectedType then

		return true

	end

	logger:warnf( "Got non-nil non-%s %s of type: %s", 
					expectedType, varName, type( var ) )

	return false

end

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

--[[
	Returns a model whose value is an Observable array of top-level albums, each containing fields:
--]]
function NmbProxyAuthErrorMonitor.startProxyAuthErrorMonitor()

	local sawAuthErrorStream =
		WFRxHttpClient.watchHttpErrors()
			:map( 
				function( ksDataOrString, headers, errorData )
					
					local isAuthError = 
							checkOptTypeWithWarn( "errorData", errorData, "table" ) and
							errorData.errorCode == "311"
							
					isAuthError = 
						isAuthError or 
						checkOptTypeWithWarn( "headers", headers, "table" ) and
						headers.status_code == "407"

					local ok, rawErrorMsg = pcall( tostring, ksDataOrString )

					isAuthError = 
						isAuthError or 
						( ok and rawErrorMsg:lower():find( "http code 407") ~= nil )
					
					if isAuthError then

						logger:error( "Proxy authentication required" )
							
						return true

					end
					
					return false
					
				end )

	local calmWindowDurationInSecs = 5.0 -- seconds

	return sawAuthErrorStream
			:filter( function( didSeeAuthError )
				return didSeeAuthError
			end )
			
			:calm( calmWindowDurationInSecs, WFRxScheduler.sharedScheduler() )
		 
end

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

return NmbProxyAuthErrorMonitor
