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

WFCatalogTestUtils.lua

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

Copyright 2020 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.

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

	-- RxLua
local Rx = require 'Rx'
local Observable = Rx.Observable

	-- WF.core.self_test
local WFRxHttpClient = require 'WFRxHttpClient'

	-- WF.core.os
local KSData = require 'KSData'
local WFAsyncFileUtils = require 'WFAsyncFileUtils'
local WFPlatformInfo = require "WFPlatformInfo"

	-- WF.core.utils
local KSPathUtils = require 'KSPathUtils'
local WFFileUtils = require 'WFFileUtils'

--============================================================================--
 --[[!
	\class WFCatalogTestUtils

	\brief This namespace provides common catalog request operations.
]]--

-- @mark WFCatalogTestUtils namespace

local WFCatalogTestUtils = {}

 --------------------------------------------------------------------------------
 --[[!
	Returns artifactory API key. The function checks that a .wfrc (mac) or a wfrc.ini(win) file exists.
    If the API key exists then the key is returned in the form of a string. If the API key has not been 
    set up an error will be thrown. 
		
	- For mac please set up a .wfrc file with an Artifactory API key. 
    - For windows please set up a file with the API key at wfrc.ini. For instructions on how 
    - to obtain an API key please refer to: https://git.corp.adobe.com/lua/wf/blob/main/doc/artifactory.md

     \return key (observable) 
 ]]--
     
function WFCatalogTestUtils.checkArtifactoryAPIKey()
	
	local artifactoryPath
	
	-- Path to artifactoryAPI key
    if WFPlatformInfo.isMac then 
        artifactoryPath = KSPathUtils.child(KSPathUtils.getStandardFilePath("home"), "/.wfrc")
	elseif WFPlatformInfo.isiOS or WFPlatformInfo.isAndroid then 
		artifactoryPath = KSPathUtils.child(KSPathUtils.getStandardFilePath("Resources"), "/wfrc")
	elseif WFPlatformInfo.isWindows then
        artifactoryPath = KSPathUtils.child(KSPathUtils.getStandardFilePath("home"), "/wfrc.ini")
	else
		error("No platform was identified.")
    end
	
	-- Check that the file exists
    if WFFileUtils.exists( artifactoryPath ) == false  then
        error( "No API key saved. Please follow the instructions https://git.corp.adobe.com/lua/wf/blob/main/doc/mac.md to set up your API key.")
	end 
	
	-- Get API key
	local result = Observable.just( artifactoryPath )
	return  result:flatMap( function( filePath )
	
					if filePath == nil then
						return Observable.just( nil )
					end

					return WFAsyncFileUtils.readFile( filePath )
						:map( function( apiKeyData )

							local key = tostring( apiKeyData )
							key = string.match(key, "apiKey%s*=%s*(%w+)")
							if key == nil then
								error( "No API key saved.Please follow the instructions https://git.corp.adobe.com/lua/wf/blob/main/doc/mac.md to set up your API key.")
							end
							apiKeyData:close()
							return key

						end )
				end )
 end 
 --------------------------------------------------------------------------------
--[[!
	Takes in the catalogStyle that is desired and returns the catalog path as it is used on the cache.
    
     \param catalogStyle (string) 
     \return catalogPath (observable) 
]]--
	
function WFCatalogTestUtils.getCachedCatalogPath(catalogStyle)

	return KSPathUtils.child(KSPathUtils.getStandardFilePath( "testdata"), 
							KSPathUtils.child(KSPathUtils.child("/.wfTestingCatalogs/", catalogStyle),
																"/Managed Catalog.mcat"))
end 

 --------------------------------------------------------------------------------
--[[!
	Saves data onto a file on the path given
    
     \param data (binary) 
     \param path (string) 
]]--

local function saveFile( data, path )

	local parent = KSPathUtils.parent( path )
	WFFileUtils.mkdir( parent )
	KSData.saveToFile( data, path )
	
end 

--------------------------------------------------------------------------------
 --[[!
    
        Checks if catalogs have been downloaded from Artifactory. If they haven't been downloaded it calls to getFileFromArtifactory
		to perform an http GET request and saves the data on .wfTestingCatalogs in the user's home directory. If the 
		catalogs are there then no request is made. For available catalogs please check WF Artifactory catalog
		at: https://artifactory-sj1.corp.adobe.com/artifactory/webapp/#/artifacts/browse/tree/General/generic-wf-testing
    
        \param catalogStyle (string) - function assumes the catalog will be located at generic-wf-testing Artifactory repo
									   under the testingCatalogs folder.
        \return Observable
]]--
	
function WFCatalogTestUtils.getCatalogsFromArtifactory( catalogStyle )

	local catalogPath = WFCatalogTestUtils.getCachedCatalogPath(catalogStyle)
	
	-- If catalogs have been downloaded already return observable
	if WFFileUtils.exists( catalogPath ) then
		return Observable.just( catalogPath)
		
	-- If catalogs have not been downloaded get catalogs from Artifactory
	else
		local filePathinArtifactory = "https://artifactory-sj1.corp.adobe.com/artifactory/generic-wf-testing/TestingCatalogs/" .. catalogStyle .. "/Managed Catalog.mcat"
		return WFCatalogTestUtils.getFileFromArtifactory( filePathinArtifactory, catalogPath )
	end 	
end
--------------------------------------------------------------------------------
 --[[!
    
        Downloads a file from Artifactory given the Artifactory path location to the file and the location where the file
		should be saved. Does this through a http GET request 
    
        \param pathInArtifactory (string) - path location in Artifactory. A path to a document located in the generic-wf-testing
											repo should begin with: https://artifactory-sj1.corp.adobe.com/artifactory/"
		\param fileDestinationPath (string) - path where the file will be saved
        \return Observable
]]--
	
function WFCatalogTestUtils.getFileFromArtifactory( pathInArtifactory, fileDestinationPath )

	return WFCatalogTestUtils.checkArtifactoryAPIKey() 
				:flatMap(function(artifactoryKey)
					
						if artifactoryKey == nil then
							error("No API Key found.")
						end							
														 
						local artifactoryURL = pathInArtifactory
						local options = {
							requestHeaders = {
								{ header = 'X-JFrog-Art-Api', value = artifactoryKey},
								},
							requestMethod = 'GET',				
							returnHttpErrorsAsData = true,						
							followRedirects = true,
						}
	
						return WFRxHttpClient.get( artifactoryURL, options )
							:map( function( data, headers )
								if data == nil then
									error("No data to save.", headers.status_code)
								end
								saveFile( data, fileDestinationPath)
								return fileDestinationPath
							end )
						end )
	end 
------------------------------------------------------------------------------------

return WFCatalogTestUtils