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 = "3.0-PREVIEW" 

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 COMPOSITE
-- -- *******************************************************************************

--[[
-----------------------------
MODELS - GET VERSION COMPOSITE ENTITY LIST
-----------------------------
	Gets information about the composite entity models.

	Request URL
	------------
		https://[location].api.cognitive.microsoft.com/luis/api/v2.0/apps/{appId}/versions/{versionId}/compositeentities[?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 composite entity model infos.
		[
			{
				"id": "bc1bae43-7904-48ad-a165-88b1910174f9",
				"name": "Reservation",
				"typeId": 4,
				"readableType": "Composite Entity Extractor",
				"children": [
					{
						"id": "63ebd752-4e81-4ce7-a698-b59b82bf5519",
						"name": "Location::To"
					},
					{
						"id": "a18eaa87-ecd9-4a67-a951-e70cf5b87c7e",
						"name": "datetime"
					}
				],
				"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/5890b47c39e2bb052c5b9c13
]]--
function LoadAllAppEntities (appId, versionId, paginated)
	assert(appId)
	assert(versionId)

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

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

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

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


--[[
-----------------------------
MODELS - GET COMPOSITE ENTITY
-----------------------------
	Gets information about the composite entity model.

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

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

		versionId string The task version ID.

		entityId string Format - guid. The 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
	-----------------------------
	The composite entity model info.
			{
				"id": "bc1bae43-7904-48ad-a165-88b1910174f9",
				"name": "Reservation",
				"typeId": 4,
				"readableType": "Composite Entity Extractor",
				"children": [
					{
						"id": "63ebd752-4e81-4ce7-a698-b59b82bf5519",
						"name": "Location::To"
					},
					{
						"id": "a18eaa87-ecd9-4a67-a951-e70cf5b87c7e",
						"name": "datetime"
					}
				],
				"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/5890b47c39e2bb052c5b9c23
]]--
function GetAppEntity (appId, entityId, versionId)
	assert(appId)
	assert(entityId)
	assert(versionId)

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

	local success, response = request.Get(uri)
	if not success then
		LogError("[LUIS_ENTITIES_COMPOSITE:GetAppEntity] Error get APP COMPOSITE ENTITIES '%s' on appId '%s' versionId: '%s' Error: '%s'", entityId, appId, versionId, json.encode(response))
		return false, response
	end

	LogInfo("[LUIS_ENTITIES_COMPOSITE:GetAppEntity] Success get APP COMPOSITE ENTITIES '%s' on appId '%s' versionId: '%s'.", entityId, appId, versionId)

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

--[[
-----------------------------
MODELS - CREATE COMPOSITE ENTITY
-----------------------------
	Este metodo el API de la version 3.0 NO lo soporta.
]]--
function CreateAppEntity (info)
	local response = {
		response = {
			error = {
				message = "Method not supported in api 3.0 PREVIEW",
				code = "UNSUPPORTED METHOD"
			}
		},
		code = 404
	}
	LogError("[LUIS_ENTITIES_COMPOSITE.v3.0_PREVIEW:CreateAppEntity] Error creating APP COMPOSITE ENTITIES on appId '%s' versionId: '%s'. Response: '%s'", info.appId, info.versionId, json.encode(response))
	return false, response
end

--[[
-----------------------------
MODELS - UPDATE COMPOSITE ENTITY
-----------------------------
	Updates the composite entity extractor.

	Request URL
	------------
		https://{endpoint}/luis/authoring/v3.0-preview/apps/{appId}/versions/{versionId}/compositeentities/{cEntityId}

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

		versionId string The task version ID.

		cEntityId string Format - guid. The composite entity extractor 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 new entity extractor name and children.
		application/json
		Sample:
			{
				"name": "Reservation",
				"children": [ "Location::To" ]
			}

	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, 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.
		This error can be returned if you are attempting to create a composite entity child when the max child count is exceeded.

		  "error": {
			"code": "BadArgument",
			"message": "Number of entity children cannot exceed 10"
		  }
	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/luis-programmatic-apis-v3-0-preview/operations/5890b47c39e2bb052c5b9c24
]]--
function RenameAppEntity (info)
	assert(info)
	assert(info.appId)
	assert(info.entityId)
	assert(info.versionId)
	assert(info.entity)

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

	local data = {
		---- Requerido
		name = info.entity.name,
		children = info.entity.children
	}
	local success, response = request.Put(uri, data)
	if not success then
		LogError("[LUIS_ENTITIES_COMPOSITE:UpdateAppEntity] Error renaming APP COMPOSITE ENTITIES '%s' on appId '%s' versionId: '%s'. Response: '%s'", info.entityId, info.appId, info.versionId, json.encode(response))
		return false, response
	end

	LogInfo("[LUIS_ENTITIES_COMPOSITE:UpdateAppEntity] Success renamed APP COMPOSITE ENTITIES '%s' on appId '%s' versionId: '%s'.", info.entityId, info.appId, info.versionId)

	return true, response
end

--[[
-----------------------------
MODELS - DELETE COMPOSITE ENTITY
-----------------------------
	Deletes a composite entity extractor from the application.

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

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

		versionId string The task version ID.

		cEntityId string Format - guid. The composite 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/5890b47c39e2bb052c5b9c25
]]--
function DeleteAppEntity (appId, entityId, versionId)
	assert(appId)
	assert(entityId)
	assert(versionId)

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

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

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

	return true, response
end
