local json = require "cjson"
local request = require "luis.request"

module(..., package.seeall)

local m_instanceOwner
function SetOwner (instanceOwner)
	m_instanceOwner = instanceOwner
end

local m_defaultAppVersion = "2.0" 

local function MakeCompleteURI (uriBaseId, uri, ...)
	uriBaseId = uriBaseId or "APPS"
	return m_instanceOwner:MakeCompleteURI(m_defaultAppVersion, uriBaseId, uri, ...) 
end

--[[
	Retorna los parametros:
		1) Si tiene paginado    : "?skip=0&take=2"
		2) Si no tiene paginado : ""
]]--
local function MakePagingParameters (params)
	local api = require "luis"
	return api.MakePagingParameters(params)
end

-- *******************************************************************************
-- API ENTITIES PREBUILT
-- -- *******************************************************************************

--[[
-----------------------------
MODELS - GET VERSION PREBUILT ENTITY LIST
-----------------------------
	Gets information about the prebuilt entity models.

	Request URL
	------------
		https://[location].api.cognitive.microsoft.com/luis/api/v2.0/apps/{appId}/versions/{versionId}/prebuilts[?skip][&take]

	Request parameters
	------------
		appId string Format - guid. The application ID.

		versionId string The task version ID.

		skip (optional) integer The number of entries to skip. Default value is 0.

		take (optional) integer The number of entries to return. Maximum page size is 500. Default is 100.

	Request headers
	------------
		Ocp-Apim-Subscription-Key string Subscription key which provides access to this API. Found in your Cognitive Services accounts.

	Request body
	------------
		..

	Response 200
	------------
		A list of prebuilt entity model infos.
		[
			{
				"id": "a18eaa87-ecd9-4a67-a951-e70cf5b87c7e",
				"name": "datetime",
				"typeId": 2,
				"readableType": "Prebuilt Entity Extractor",
				"roles": [
					{
						"id": "eb64dfeb-b54a-4b8a-b2d5-9315beea055a",
						"name": "role 1"
					},
					{
						"id": "b3abd65c-d187-4bd0-9fd2-81cbd0dd2026",
						"name": "role 2"
					}
				]
			}
		]

	Response 429
	------------
		Rate limit is exceeded.

	Response 400
	------------
		This error can be returned if the request's parameters are incorrect meaning the required parameters are missing, malformed, or too large.

	Response 401
	------------
		You do not have access.

		Reasons can include:

		used endpoint subscription key, instead of authoring key
		invalid, malformed, or empty authoring key
		authoring key doesn't match region
		you are not the owner or collaborator
		invalid order of API calls

	Response 403
	------------
		Total monthly key quota limit exceeded

	Referencia: https://westus.dev.cognitive.microsoft.com/docs/services/5890b47c39e2bb17b84a55ff/operations/5890b47c39e2bb052c5b9c17
]]--
function LoadAllAppEntities (appId, versionId, paginated)
	assert(appId)
	assert(versionId)

	local uri = MakeCompleteURI("APPS", "%s/versions/%s/prebuilts", appId, versionId)
	uri = uri .. MakePagingParameters(paginated)

	local success, response = request.Get(uri)
	if not success then
		LogError("[LUIS_ENTITIES_PREBUILT:LoadAllAppEntities] Error loading all APP PREBUILT ENTITIES on appId '%s' versionId: '%s'. Error: '%s'", appId, versionId, json.encode(response))
		return false, response
	end

	LogInfo("[LUIS_ENTITIES_PREBUILT:LoadAllAppEntities] Success loaded all APP PREBUILT ENTITIES on appId '%s' versionId: '%s'.", appId, versionId)

	local encodedEntities = table.concat(response)
	return true, encodedEntities
end

--[[
-----------------------------
MODELS - ADD PREBUILT ENTITY LIST
-----------------------------
	Adds a list of prebuilt entity extractors to the application.

	Request URL
	------------
		https://[location].api.cognitive.microsoft.com/luis/api/v2.0/apps/{appId}/versions/{versionId}/prebuilts

	Request parameters
	------------
		appId string Format - guid. The application ID.
		versionId string The task version ID.

	Request headers
	------------
		Content-Type (optional) string Media type of the body sent to the API.
		Ocp-Apim-Subscription-Key string Subscription key which provides access to this API. Found in your Cognitive Services accounts.

	Request body
	------------
		A model object containing the name and children of the new entity extractor.
		The name of the entity must be unique in the application and must not be used by a prebuilt entity.

		application/json
		Sample
			[ "datetimeV2" ]

	Response 201
	------------
		An array of the created prebuilt extractor infos.

		[
			{
				"id": "a18eaa87-ecd9-4a67-a951-e70cf5b87c7e",
				"name": "datetimeV2",
				"typeId": 2,
				"readableType": "Prebuilt Entity Extractor"
			}
		]

	Response 429
	------------
		Rate limit is exceeded.

	Response 400
	------------
		This error can be returned if the request's parameters are incorrect meaning the required parameters are missing, malformed, or too large.

		This error can be returned if the request's body is incorrect meaning the JSON is missing, malformed, or too large.


	Response 401
	------------
		You do not have access.

		Reasons can include:

		used endpoint subscription key, instead of authoring key
		invalid, malformed, or empty authoring key
		authoring key doesn't match region
		you are not the owner or collaborator
		invalid order of API calls

	Response 403
	------------
		Total monthly key quota limit exceeded

	Referencia: https://westus.dev.cognitive.microsoft.com/docs/services/5890b47c39e2bb17b84a55ff/operations/5890b47c39e2bb052c5b9c16
]]--
function CreateAppEntity (info)
	assert(type(info) == "table")
	assert(info.appId)
	assert(info.versionId)
	assert(info.entity)

	local uri = MakeCompleteURI("APPS", "%s/versions/%s/prebuilts", info.appId, info.versionId)
	local data = info.entity.list

	local success, response = request.Post(uri, data)
	if not success then
		LogError("[LUIS_ENTITIES_PREBUILT:CreateAppEntity] Error Adding APP PREBUILT ENTITIES on appId '%s' versionId: '%s'. Response: '%s'", info.appId, info.versionId, json.encode(response))
		return false, response
	end

	local entityId = table.concat(response)
	LogInfo("[LUIS_ENTITIES_PREBUILT:CreateAppEntity] Success Added APP PREBUILT ENTITIES on appId '%s', entityId: '%s' versionId: '%s'.", info.appId, entityId, info.versionId)

	return true, entityId
end

--[[
-----------------------------
MODELS - DELETE PREBUILT ENTITY
-----------------------------
	Deletes a prebuilt entity extractor from the application.

	Request URL
	------------
		https://[location].api.cognitive.microsoft.com/luis/api/v2.0/apps/{appId}/versions/{versionId}/prebuilts/{prebuiltId}

	Request parameters
	------------
		appId string Format - guid. The application ID.

		versionId string The task version ID.

		hEntityId string Format - guid. The prebuilt entity extractor ID.

	Request headers
	------------
		Ocp-Apim-Subscription-Key string Subscription key which provides access to this API. Found in your Cognitive Services accounts.

	Request body
	------------

	Response 200
	------------
		Empty response

	Response 429
	------------
		Rate limit is exceeded.


	Response 400
	------------
		This error can be returned if the request's parameters are incorrect meaning the required parameters are missing or malformed.

	Response 401
	------------
		You do not have access.

		Reasons can include:
			used endpoint subscription key, instead of authoring key
			invalid, malformed, or empty authoring key
			authoring key doesn't match region
			you are not the owner or collaborator
			invalid order of API calls

	Response 403
	------------
		Total monthly key quota limit exceeded

	Referencia: https://westus.dev.cognitive.microsoft.com/docs/services/5890b47c39e2bb17b84a55ff/operations/5890b47c39e2bb052c5b9c2b
]]--
function DeleteAppEntity (appId, entityId, versionId)
	assert(appId)
	assert(entityId)
	assert(versionId)

	local uri = MakeCompleteURI("APPS", "%s/versions/%s/prebuilts/%s", appId, versionId, entityId)

	local success, response = request.Delete(uri)
	if not success then
		LogError("[LUIS_ENTITIES_PREBUILT:DeleteAppEntity] Error deleting APP PREBUILT ENTITIES '%s' versionId: '%s' on appId '%s'. Response: '%s'", entityId, versionId, appId, json.encode(response))
		return false, response
	end

	LogInfo("[LUIS_ENTITIES_PREBUILT:DeleteAppEntity] Success deleted APP PREBUILT ENTITIES '%s' versionId: '%s' on appId '%s'.", entityId, versionId, appId)

	return true, response
end


--[[
-----------------------------
MODELS - GET AVAILABLE PREBUILT ENTITY LIST
-----------------------------
	Gets all the available prebuilt entities for the application based on the application's culture.

	Request URL
	------------
		https://[location].api.cognitive.microsoft.com/luis/api/v2.0/apps/{appId}/versions/{versionId}/listprebuilts

	Request parameters
	------------
		appId string Format - guid. The application ID.

		versionId string The task version ID.


	Request headers
	------------
		Ocp-Apim-Subscription-Key string Subscription key which provides access to this API. Found in your Cognitive Services accounts.

	Request body
	------------
		..

	Response 200
	------------
		A list of the possible prebuilt entity extractors.
		[
			{
				"name": "geography",
				"description": "Continents, Countries, Cities, Post codes, and other points of interest",
				"examples": "Antarctica, Portugal, Dubai, Sanjiang County, Lake Pontchartrain, CB3 0DS"
			},
			{
				"name": "datetime",
				"description": "Dates and times, resolved to a canonical form",
				"examples": "June 23, 1976, Jul 11 2012, 7 AM, 6:49 PM, tomorrow at 7 AM"
			},
			{
				"name": "email",
				"description": "Email Addresses",
				"examples": "user@site.net, user_name@mysite.com.eg"
			},
			{
				"name": "url",
				"description": "Websites URLs",
				"examples": "www.website.com, http://website.net?name=my_name&age=10, https://www.mywebsite.net.eg/page"
			},
			{
				"name": "phoneNumber",
				"description": "US phone numbers",
				"examples": "123-456-7890, +1 123 456 789, (123)456-789"
			}
		]

	Response 429
	------------
		Rate limit is exceeded.

	Response 400
	------------
		This error can be returned if the request's parameters are incorrect meaning the required parameters are missing, malformed, or too large.

	Response 401
	------------
		You do not have access.

		Reasons can include:

		used endpoint subscription key, instead of authoring key
		invalid, malformed, or empty authoring key
		authoring key doesn't match region
		you are not the owner or collaborator
		invalid order of API calls

	Response 403
	------------
		Total monthly key quota limit exceeded

	Referencia: https://westus.dev.cognitive.microsoft.com/docs/services/5890b47c39e2bb17b84a55ff/operations/5890b47c39e2bb052c5b9c18
]]--
function LoadAvailablePrebuiltList (appId, versionId)
	assert(appId)
	assert(versionId)

	local uri = MakeCompleteURI("APPS", "%s/versions/%s/listprebuilts", appId, versionId)

	local success, response = request.Get(uri)
	if not success then
		LogError("[LUIS_ENTITIES_PREBUILT:LoadAvailablePrebuiltList] Error loading all AVAILABLE PREBUILT ENTITY LIST on appId '%s' versionId: '%s'. Error: '%s'", appId, versionId, json.encode(response))
		return false, response
	end

	LogInfo("[LUIS_ENTITIES_PREBUILT:LoadAvailablePrebuiltList] Success loaded all AVAILABLE PREBUILT ENTITY LIST on appId '%s' versionId: '%s'.", appId, versionId)

	local encodedAvailablePrebuiltList = table.concat(response)
	--LogDebug("[LUIS_ENTITIES_PREBUILT:LoadAvailablePrebuiltList] All Available Prebuilt List: '%s'", encodedAvailablePrebuiltList)

	-- Ahora se deben de excluir de la lista, los prebuilt que han deprecado.
	local allAvailablePrebuiltList = json.decode(encodedAvailablePrebuiltList)
	local availablePrebuiltList = {}
	for _, prebuilt in ipairs(allAvailablePrebuiltList) do
		if (prebuilt.name or ""):lower() ~= "datetime" then
			table.insert(availablePrebuiltList, prebuilt)
		else
			LogInfo("[LUIS_ENTITIES_PREBUILT:LoadAvailablePrebuiltList] Exclude '%s' deprecated Prebuilt entity.", prebuilt.name)
		end
	end
	local encodedAvailablePrebuiltList = json.encode(availablePrebuiltList)

	return true, encodedAvailablePrebuiltList
end
