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

KSKeychainServiceImp.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.

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

Implementation for keychain services. This file should not be accessed by any
code other than KSKeychainService.

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

	-- wichitafoundation.core.lua.threading
local WFCurrentThread = require 'WFCurrentThread'
local WFRequestDispatcher = require 'WFRequestDispatcher'

	-- services.keychain_store
local KSKeychainManager = require 'KSKeychainManager'
local WFCapabilities = require 'WFCapabilities'

	-- WF.core.logger
local WFLogger = require 'WFLogger'

local inMemoryKeychain = {}
	-- Used for unit testing, to bypass password dialogs and such
	-- that plague our Automation. Also used as a backup when the
	-- standard KSKeychainManager APIs fail to write ( which can
	-- be caused by low memory as seen in unit tests ).
	
--------------------------------------------------------------------------------

local logger = WFLogger 'KSKeychainServiceImp'

WFCurrentThread.setThreadPriority( '< low >' )

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

WFRequestDispatcher.onMessageDo {

	message = 'write',
	simpleResponses = true, -- Avoids the need for the reactive logic
	
	handler = function( key, value )

		assert( type( key ) == 'string', "KSKeychainService.write: key must be a string" )
		assert( type( value ) == 'string', "KSKeychainService.write: value must be a string" )

		inMemoryKeychain[ key ] = value
		
		if WFCapabilities.getCapability "KSKeychainService_securityMode" ~= 'inMemory' then
			
			local success, maybeError = pcall( KSKeychainManager.write, key, value )
			
			if not success then
				logger:warnf( "KSKeychainManager.write failed with error: %s", maybeError )
			end
			
		end
		
	end,

}

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

WFRequestDispatcher.onMessageDo {

	message = 'read',
	simpleResponses = true, -- Avoids the need for the reactive logic
	
	handler = function( key )
	
		assert( type( key ) == 'string', "KSKeychainService.read: key must be a string" )
	
		if WFCapabilities.getCapability "KSKeychainService_securityMode" == 'inMemory' then
			return inMemoryKeychain[ key ]
		else
			return KSKeychainManager.read( key ) or inMemoryKeychain[ key ]
		end
		
	end,

}

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

WFRequestDispatcher.onMessageDo {

	message = 'delete',
	simpleResponses = true, -- Avoids the need for the reactive logic
	
	handler = function( key )

		assert( type( key ) == 'string', "KSKeychainService.delete: key must be a string" )

		inMemoryKeychain[ key ] = nil

		if WFCapabilities.getCapability "KSKeychainService_securityMode" ~= 'inMemory' then
			KSKeychainManager.delete( key )
		end

	end,

}

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

WFRequestDispatcher.onMessage( 'DEBUG_dumpCoverageP', function( path )

	require 'SetupCoverage'.dumpCoverage( path )

	return require 'KSPromises'.resolvedPromiseP( 'data', true )

end )
