require("socket")
require("md5")
local url = require("socket.url")
local http = require("socket.http")
local ltn12 = require("ltn12")
local json = require("json")
local m_loginUser, m_loginVCC
local m_i6ServerIP = "127.0.0.1"
local m_i6ServerPort = "8082"

module(..., package.seeall)

local function ParseId (id)
	return string.match(id, "(.+)@([^@]+)$")
end

local m_cookie
local function SetCookie (c)
--	LogDebug("--> SetCookie: '%s'", c)
	m_cookie = c
end

local function BuildCompleteUrl (url)
	return string.format("http://%s:%s/inconcert/apps/%s", m_i6ServerIP, m_i6ServerPort, url)
end

local function Get (url, headers)
	local uri = BuildCompleteUrl(url)
	-- LogDebug("")
	-- LogDebug("-- GET start --")
	-- LogDebug("GET URI: %s", uri)
	headers = headers or {}
	if m_cookie and string.len(m_cookie) then
		headers["Cookie"] = m_cookie
	end

	-- LogDebug("GET -> headers; %s", json.encode(headers))
	local responseBody = {}
	local result, code, header = http.request{
		url = uri,
		method = "GET",
		headers = headers,
		sink = ltn12.sink.table(responseBody)
	}
	local encodedContent = table.concat(responseBody, "")
	-- LogDebug("GET-> result: '%s', code: '%s', header: '%s'.", result, code, json.encode(header))
	-- LogDebug("GET-> encodedContent length: '%s'", #(encodedContent or ""))
	-- LogDebug("GET-> encodedContent content: '%s'", encodedContent)
	-- LogDebug("-- GET end --")
	-- LogDebug("")
	if code == 200 then
		return true, encodedContent
	end
	LogError("[REPORTER.REQUEST.Get] result: '%s', code: '%s', header: '%s'.", result, code, json.encode(header))
	return false, encodedContent, code
end

local function Post (url, body, headers)
	headers = headers or {}
	headers["content-length"] = body and string.len(body) or 0
	if m_cookie and string.len(m_cookie) then
		headers["Cookie"] = m_cookie
	end
	local response_body = {}
	local result, code, header, statusline = socket.http.request{
		url = BuildCompleteUrl(url),
		method = "POST",
		headers = headers,
		source = ltn12.source.string(body),
		sink = ltn12.sink.table(response_body)
	}
	local response = table.concat(response_body, "")
	if code == 200 then
		return true, response
	end
	return false, response, code
end

local function LoginUser (username, callcenterId, password, token, applicationName)
	local textToEncode = string.lower(username) .. password
	local hash = md5.sumhexa( md5.sumhexa(textToEncode) .. token.loginToken)
	local params = "hash=" .. hash .. "&username=" .. url.escape(username) .. 
					"&loginToken=" .. token.loginToken .. "&callcenter=" .. callcenterId .. 
					"&app=" .. url.escape(applicationName)
	local url = "agent/login/authenticate/"
	local headers = {
		['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'
	}
	local result, response = Post(url, params, headers)
	if result then
		local data = json.decode(response)
		if data.status then
			m_cookie = "AUTH_SID_AGENT=".. data.authToken
			SetCookie(m_cookie)
			return true
		else
			return false, data.failCause
		end
	else
		LogError("[REPORTER.REQUEST.LoginUser] Error logging in: "..response)
	end	
	return false, response
end

local function Login (user, vcc, password, application)
	local params = "username=" .. url.escape(user) .. "&callcenter=" .. vcc
	local url = "agent/login/getToken/"
	local headers = {
		['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'
	}
	local response, tokenResponse = Post(url, params, headers)
	if response then
		local response = json.decode(tokenResponse)
		--LogDebug("GET TOKEN RESPONSE: "..tokenResponse)
		local result, reason = LoginUser(user, vcc, password, response, application)
		return result, reason
	else
		LogError("[REPORTER.REQUEST.Login] Error getting token: "..tokenResponse)
	end
	return false, "Error getting token: "..tokenResponse
end

function DoLogin ()
	return Login("admin", "system", "1234", "agent")
end

function Logout ()
	LogDebug("[REPORTER.REQUEST.Logout] Login out")
	local success, response, code = Post("agent/login/logout/")
	SetCookie(nil)
	return success, response, code
end

function GetCallConversationPartsOfVcc (interactionId, vcc)
	LogInfo("[REPORTER.REQUEST.GetCallConversationPartsOfVcc] Retrieving Call Conversation '%s' Parts of Vcc: '%s'", interactionId, vcc)
	local uri = "allegro/supervisor/get_interaction_records_of_vcc/" .. interactionId .. "/" .. vcc
	return Get(uri)
end
