module(..., package.seeall)

local utils = require "luis.utils"
local m_datasource

function GetName ()
	return "VCCs"
end

function GetDefinition (datasource)
	m_datasource = datasource
	return _M
end

function GetTimezone (timezoneId)
	local keyspace = utils.GetDatasource():CassandraConnection( "Agent" )
	local columns = keyspace:GetSliceRange(timezoneId, "Timezones", "",
		{
			--column_names = {},
			slice_range = {
				start = "",
				finish = "",
				reversed = true,
				count = 10
			}
		}
	)
	keyspace:Close()
	if not columns or not next(columns) then
		error(("Timezone %q not found"):format(timezoneId))
	end
	local row = {}
	for k, column in pairs(columns) do
		row[column.name] = column.value
	end
	return {
		id = timezoneId,                              -- ej: "UYT",
		offset = tonumber(row.TimeZone),              -- ej: -3,
		minutes = tonumber(row.TimeZoneMinutes),      -- ej: 0,
		dst = (tonumber(row.DaylightSavingTime) ~= 0) -- ej: true
	}
end

function VCCExists (vcc, keyspace)
	return utils.GetColumnValue({
		keyspace = keyspace or "Agent",
		columnFamily = "VCCs",
		key = vcc,
		column = "Id"
	})
end

--[[
	APPLICATIONS -------------------------------------
]]--

function GetApplicationMsCognitiveService (vcc, appId, keyspace)
	return utils.GetColumnValue({
		keyspace = keyspace or "Agent",
		columnFamily = "VCCCognitiveServicesApplications",
		key = vcc,
		column = appId
	})
end

function GetApplicationsMsCognitiveServices (vcc, keyspace)
	return utils.GetAllColumns({
		keyspace = keyspace or "Agent",
		columnFamily = "VCCCognitiveServicesApplications",
		key = vcc,
		columns = {}
	}) or {}
end

local function SaveApplicationMsCognitiveServices (vcc, appsMsCognitiveServices, keyspace)
	local rows = {}
	rows[vcc] = appsMsCognitiveServices
	utils.SaveRows({ keyspace = keyspace or "Agent", columnFamily = "VCCCognitiveServicesApplications", rows = rows })
end

function UpdateApplicationMsCognitiveServices (vcc, appId, info, keyspace, excludeFields)
	excludeFields = excludeFields or {} -- Lista de Columns que no se deben actualizar (opcional)
	local appsMsCognitiveServices = GetApplicationsMsCognitiveServices(vcc, keyspace)
	appsMsCognitiveServices[appId] = appsMsCognitiveServices[appId] or {}

	for name, value in pairs(info or {}) do
		if not excludeFields[name] then
			appsMsCognitiveServices[appId][name] = value
		end
	end

	SaveApplicationMsCognitiveServices(vcc, appsMsCognitiveServices, keyspace)
end

function RemoveApplicationPublishAppInfo (vcc, appId, keyspace)
	local appsMsCognitiveServices = GetApplicationsMsCognitiveServices(vcc, keyspace)
	if not appsMsCognitiveServices or not appsMsCognitiveServices[appId] then
		return
	end
	appsMsCognitiveServices[appId].inconcertInfo = nil
	SaveApplicationMsCognitiveServices(vcc, appsMsCognitiveServices, keyspace)
	return true
end

function RemoveApplicationMsCognitiveServices (vcc, appId, keyspace)
	local apps = {}
	table.insert(apps, appId)
	utils.RemoveColumns({
		keyspace = keyspace or "Agent",
		columnFamily = "VCCCognitiveServicesApplications",
		rows = {
			[vcc] = apps
		}
	})
end

--[[
	SUBSCRIPTIONS -------------------------------------
]]--

function HasConfiguredDemoSubscriptionsInVcc (vcc, keyspace)
	local list = GetSubscriptionsKeysMsCognitiveServices(vcc, keyspace)
	local isDemo = false
	local demoSubscription
	for _, info in pairs(list) do
		if info.isDemo then
			isDemo = true
			demoSubscription = info
			break
		end
	end
	return isDemo, demoSubscription
end

function GetSubscriptionsKeysMsCognitiveServices (vcc, keyspace)
	return utils.GetAllColumns({
		keyspace = keyspace or "Agent",
		columnFamily = "VCCCognitiveServicesSubscriptionsKeys",
		key = vcc,
		columns = {}
	}) or {}
end

local function SaveSubscriptionsKeysMsCognitiveServices (vcc, vccSubscriptionsKeys, keyspace)
	local rows = {}
	rows[vcc] = vccSubscriptionsKeys
	utils.SaveRows({ keyspace = keyspace or "Agent", columnFamily = "VCCCognitiveServicesSubscriptionsKeys", rows = rows })
end

local function AddVCCBySubscriptionKey (vcc, key, keyspace)
	local closeKeyspace = false
	if not keyspace then
		keyspace = utils.GetDatasource():CassandraConnection("Agent")
		closeKeyspace = true
	end
	keyspace:InsertColumn(key, "VCCsByCognitiveServicesSubscriptionKey", vcc, "")
	if closeKeyspace then
		keyspace:Close()
	end
end

function AssignSubscriptionKeyToVCC (vcc, key, subscripitonInfo, keyspace)
	local vccSubscriptionsKeys = GetSubscriptionsKeysMsCognitiveServices(vcc, keyspace)
	vccSubscriptionsKeys[key] = subscripitonInfo or vccSubscriptionsKeys[key] or {}
	SaveSubscriptionsKeysMsCognitiveServices(vcc, vccSubscriptionsKeys, keyspace)
	AddVCCBySubscriptionKey(vcc, key, keyspace)
end

local function RemoveVCCBySubscriptionKey (vcc, key, keyspace)
	local closeKeyspace = false
	if not keyspace then
		keyspace = utils.GetDatasource():CassandraConnection("Agent")
		closeKeyspace = true
	end
	keyspace:RemoveColumn(key, "VCCsByCognitiveServicesSubscriptionKey", vcc)
	if closeKeyspace then
		keyspace:Close()
	end
end

function UnAssignSubscriptionKeyOfVCC (vcc, key, keyspace)
	local vccSubscriptionsKeys = {}
	table.insert(vccSubscriptionsKeys, key)
	utils.RemoveColumns({
		keyspace = keyspace or "Agent",
		columnFamily = "VCCCognitiveServicesSubscriptionsKeys",
		rows = {
			[vcc] = vccSubscriptionsKeys
		}
	})
	RemoveVCCBySubscriptionKey(vcc, key, keyspace)
end

function LoadVCCsBySubscriptionKey (key, keyspace)
	local vccs = utils.GetAllColumns({
		keyspace = keyspace or "Agent",
		columnFamily = "VCCsByCognitiveServicesSubscriptionKey",
		key = key
	}) or {}
	return vccs
end

--[[
	AZURE ACCOUNT -------------------------------------
]]--

function LoadVCCsByAzureAccount (key, keyspace)
	local vccs = utils.GetAllColumns({
		keyspace = keyspace or "Agent",
		columnFamily = "VCCsByCognitiveServicesAzureAccount",
		key = key
	}) or {}
	return vccs
end

function GetAzureAccountsMsCognitiveServices (vcc, keyspace)
	return utils.GetAllColumns({
		keyspace = keyspace or "Agent",
		columnFamily = "VCCCognitiveServicesAzureAccounts",
		key = vcc,
		columns = {}
	}) or {}
end

local function SaveAzureAccountsMsCognitiveServices (vcc, vccAzureAccounts, keyspace)
	local rows = {}
	rows[vcc] = vccAzureAccounts
	utils.SaveRows({keyspace = keyspace or "Agent", columnFamily = "VCCCognitiveServicesAzureAccounts", rows = rows})
end

local function AddVCCByAzureAccount (vcc, key, keyspace)
	local closeKeyspace = false
	if not keyspace then
		keyspace = utils.GetDatasource():CassandraConnection("Agent")
		closeKeyspace = true
	end
	keyspace:InsertColumn(key, "VCCsByCognitiveServicesAzureAccount", vcc, "")
	if closeKeyspace then
		keyspace:Close()
	end
end

function AssignAzureAccountToVCC (vcc, azureInfo, keyspace)
	local key = azureInfo.AzureSubscriptionId
	local vccAzureAccounts = GetAzureAccountsMsCognitiveServices(vcc, keyspace)
	vccAzureAccounts[key] = azureInfo or vccAzureAccounts[key] or {}
	SaveAzureAccountsMsCognitiveServices(vcc, vccAzureAccounts, keyspace)
	AddVCCByAzureAccount(vcc, key, keyspace)
end

local function RemoveVCCByAzureAccount (vcc, key, keyspace)
	local closeKeyspace = false
	if not keyspace then
		keyspace = utils.GetDatasource():CassandraConnection("Agent")
		closeKeyspace = true
	end
	keyspace:RemoveColumn(key, "VCCsByCognitiveServicesAzureAccount", vcc)
	if closeKeyspace then
		keyspace:Close()
	end
end

function UnAssignAzureAccountOfVCC (vcc, key, keyspace)
	local vccAzureAccounts = {}
	table.insert(vccAzureAccounts, key)
	utils.RemoveColumns({
		keyspace = keyspace or "Agent",
		columnFamily = "VCCCognitiveServicesAzureAccounts",
		rows = {
			[vcc] = vccAzureAccounts
		}
	})
	RemoveVCCByAzureAccount(vcc, key, keyspace)
end
----------------------------

--[[
	AZURE TENANT ACCOUNT -------------------------------------
]]--
function LoadVCCsByTenantAzureAccount (key, keyspace)
	local vccs = utils.GetAllColumns({
		keyspace = keyspace or "Agent",
		columnFamily = "VCCsByCognitiveServicesTenants",
		key = key
	}) or {}
	return vccs
end

function GetTenantAzureAccountsMsCognitiveServices (vcc, keyspace)
	return utils.GetAllColumns({
		keyspace = keyspace or "Agent",
		columnFamily = "VCCCognitiveServicesTenants",
		key = vcc,
		columns = {}
	}) or {}
end

function GetAzureLanguageStudioAccountsMsCognitiveServices (vcc, keyspace)
	
	return utils.GetAllColumns({
		keyspace = keyspace or "Agent",
		columnFamily = "VCCCognitiveServicesLanguageStudio",
		key = vcc,
		columns = {}
	}) or {}
end

local function SaveTenantAzureAccountsMsCognitiveServices (vcc, vccTenantAzureAccounts, keyspace)
	local rows = {}
	rows[vcc] = vccTenantAzureAccounts
	utils.SaveRows({keyspace = keyspace or "Agent", columnFamily = "VCCCognitiveServicesTenants", rows = rows})
end

local function SaveAzureLanguageStudioAccountsMsCognitiveServices (vcc, vccAzureLanguageStudioAccounts, keyspace)
	local rows = {}
	rows[vcc] = vccAzureLanguageStudioAccounts
	utils.SaveRows({keyspace = keyspace or "Agent", columnFamily = "VCCCognitiveServicesLanguageStudio", rows = rows})
end

local function AddVCCByTenantAzureAccount (vcc, key, keyspace)
	local closeKeyspace = false
	if not keyspace then
		keyspace = utils.GetDatasource():CassandraConnection("Agent")
		closeKeyspace = true
	end
	keyspace:InsertColumn(key, "VCCsByCognitiveServicesTenants", vcc, "")
	if closeKeyspace then
		keyspace:Close()
	end
end

local function AddVCCByAzureLanguageStudioAzureAccount (vcc, key, keyspace)
	local closeKeyspace = false
	if not keyspace then
		keyspace = utils.GetDatasource():CassandraConnection("Agent")
		closeKeyspace = true
	end
	keyspace:InsertColumn(key, "VCCsByCognitiveServicesLanguageStudio", vcc, "")
	if closeKeyspace then
		keyspace:Close()
	end
end

function AssignTenantAzureAccountToVCC (vcc, tenantInfo, keyspace)
	local key = tenantInfo.tenant_id
	local vccTenantAzureAccounts = GetTenantAzureAccountsMsCognitiveServices(vcc, keyspace)
	vccTenantAzureAccounts[key] = tenantInfo or vccTenantAzureAccounts[key] or {}
	SaveTenantAzureAccountsMsCognitiveServices(vcc, vccTenantAzureAccounts, keyspace)
	AddVCCByTenantAzureAccount(vcc, key, keyspace)
end

function AssignAzureLanguageStudioAccountToVCC (vcc, languageStudioInfo, keyspace)
	local key = languageStudioInfo.azure_subscription_id
	local vccAzureLanguageStudioAccounts = GetAzureLanguageStudioAccountsMsCognitiveServices(vcc, keyspace)
	vccAzureLanguageStudioAccounts[key] = languageStudioInfo or vccAzureLanguageStudioAccounts[key] or {}
	SaveAzureLanguageStudioAccountsMsCognitiveServices(vcc, vccAzureLanguageStudioAccounts, keyspace)
	AddVCCByAzureLanguageStudioAzureAccount(vcc, key, keyspace)
end

local function RemoveVCCByTenantAzureAccount (vcc, key, keyspace)
	local closeKeyspace = false
	if not keyspace then
		keyspace = utils.GetDatasource():CassandraConnection("Agent")
		closeKeyspace = true
	end
	keyspace:RemoveColumn(key, "VCCsByCognitiveServicesTenants", vcc)
	if closeKeyspace then
		keyspace:Close()
	end
end

local function RemoveVCCByAzureLanguageStudioAccount (vcc, key, keyspace)
	local closeKeyspace = false
	if not keyspace then
		keyspace = utils.GetDatasource():CassandraConnection("Agent")
		closeKeyspace = true
	end
	keyspace:RemoveColumn(key, "VCCsByCognitiveServicesLanguageStudio", vcc)
	if closeKeyspace then
		keyspace:Close()
	end
end

function UnAssignTenantAzureAccountOfVCC (vcc, key, keyspace)
	local vccTenantAzureAccounts = {}
	table.insert(vccTenantAzureAccounts, key)
	utils.RemoveColumns({
		keyspace = keyspace or "Agent",
		columnFamily = "VCCCognitiveServicesTenants",
		rows = {
			[vcc] = vccTenantAzureAccounts
		}
	})
	RemoveVCCByTenantAzureAccount(vcc, key, keyspace)
end

function UnAssignAzureLanguageStudioAccountOfVCC (vcc, key, keyspace)
	local vccAzureLanguageStudioAccounts = {}
	table.insert(vccAzureLanguageStudioAccounts, key)
	utils.RemoveColumns({
		keyspace = keyspace or "Agent",
		columnFamily = "VCCCognitiveServicesLanguageStudio",
		rows = {
			[vcc] = vccAzureLanguageStudioAccounts
		}
	})
	RemoveVCCByAzureLanguageStudioAccount(vcc, key, keyspace)
end

