local j=require(script.Privates)local R={"\080\079\083\084";"\080\085\084";"\080\065\084\067\072"}local A={"\071\069\084";"\068\069\076\069\084\069"}local d={}d.__index=d function d.new(j,R)if string.sub(j,#j,#j)=="\047"then j=string.sub(j,1,#j-1)end if not string.find(j,"\094\104\116\116\112\091\115\093\063\058\047\047")then error("\082\111\111\116 \109\117\115\116 \105\110\099\108\117\100\101 \104\116\116\112\058\047\047 \111\114 \104\116\116\112\115\058\047\047 \097\116 \116\104\101 \098\101\103\105\110\110\105\110\103")end return setmetatable({AccessKey=R,Root=j},d)end local function B(...)local R,A=(j.HttpGetAsync(...)):await()return R and A or false end local function W(...)local R,A=(j.HttpPostAsync(...)):await()return R and A or false end local function Y(j,R,A,d,B)local W=d or{}W["\112\114\111\120\121-\097\099\099\101\115\115-\107\101\121"]=j.AccessKey W["\112\114\111\120\121-\116\097\114\103\101\116"]=A if B then W["\112\114\111\120\121-\116\097\114\103\101\116-\111\118\101\114\114\105\100\101-\112\114\111\116\111"]=B end if R~="\071\069\084"and R~="\080\079\083\084"then W["\112\114\111\120\121-\116\097\114\103\101\116-\111\118\101\114\114\105\100\101-\109\101\116\104\111\100"]=R end if d then for j,R in next,d do if string.lower(j)=="\117\115\101\114-\097\103\101\110\116"then W["\117\115\101\114-\097\103\101\110\116"]=nil W["\112\114\111\120\121-\111\118\101\114\114\105\100\101-\117\115\101\114-\097\103\101\110\116"]=R end end end return W end local function m(j)return function(R,A,d,B,m,s,E,N)local V=Y(R,j,A,E,N)return W(R.Root..d,B,m,s,V)end end local function s(j)return function(R,A,d,W,m,s)local E=Y(R,j,A,m,s)return B(R.Root..d,W,E)end end local function E(j)return function(R,A,...)local d,B=string.find(A,"\058\047\047")local W=string.find(A,"\047",B+1)or#A+1 return j(R,string.sub(A,B+1,W-1),string.sub(A,W),...)end end local function N(j,R,A)d[string.upper(string.sub(R,1,1))..string.lower(string.sub(R,2))]=E(j(R))end for j,R in ipairs(R)do N(m,R)end for j,R in ipairs(A)do N(s,R)end return d
local Privates = require(script.Privates)

local POST_METHODS = {"POST", "PUT", "PATCH"}
local GET_METHODS = {"GET", "DELETE"}

local ProxyService = {}
ProxyService.__index = ProxyService

function ProxyService.new(Root, AccessKey)
	if string.sub(Root, #Root, #Root) == "/" then
		Root = string.sub(Root, 1, #Root - 1)
	end

	if not string.find(Root, "^http[s]?://") then
		error("Root must include http:// or https:// at the beginning")
	end

	return setmetatable({
		AccessKey = AccessKey;
		Root = Root;
	}, ProxyService)
end

-- To-Do: Convert these to use RequestAsync.
local function HttpGet(...)
	local Success, Data = Privates.HttpGetAsync(...):await()
	return Success and Data or false
end

local function HttpPost(...)
	local Success, Data = Privates.HttpPostAsync(...):await()
	return Success and Data or false
end

local function GetHeaders(self, Method, Target, Headers, OverrideProto)
	local SendHeaders = Headers or {}
	SendHeaders["proxy-access-key"] = self.AccessKey
	SendHeaders["proxy-target"] = Target

	if OverrideProto then
		SendHeaders["proxy-target-override-proto"] = OverrideProto
	end

	if Method ~= "GET" and Method ~= "POST" then
		SendHeaders["proxy-target-override-method"] = Method
	end

	if Headers then
		for Header, Value in next, Headers do
			if string.lower(Header) == "user-agent" then
				SendHeaders["user-agent"] = nil
				SendHeaders["proxy-override-user-agent"] = Value
			end
		end
	end

	return SendHeaders
end

local function GeneratePostHandler(Method)
	return function(self, Target, Path, Data, ContentType, Compress, Headers, OverrideProto)
		local SendHeaders = GetHeaders(self, Method, Target, Headers, OverrideProto)
		return HttpPost(self.Root .. Path, Data, ContentType, Compress, SendHeaders)
	end
end

local function GenerateGetHandler(Method)
	return function(self, Target, Path, NoCache, Headers, OverrideProto)
		local SendHeaders = GetHeaders(self, Method, Target, Headers, OverrideProto)
		return HttpGet(self.Root .. Path, NoCache, SendHeaders)
	end
end

local function UrlProcessor(Function)
	return function(self, Url, ...)
		local _, EndPosition = string.find(Url, "://")
		local NextPosition = string.find(Url, "/", EndPosition + 1) or #Url + 1
		return Function(self, string.sub(Url, EndPosition + 1, NextPosition - 1), string.sub(Url, NextPosition), ...)
	end
end

local function GenerateWithHandler(Handler, Method, HandlerMethod)
	ProxyService[string.upper(string.sub(Method, 1, 1)) .. string.lower(string.sub(Method, 2))] = UrlProcessor(Handler(Method))
end

for _, Method in ipairs(POST_METHODS) do
	GenerateWithHandler(GeneratePostHandler, Method)
end

for _, Method in ipairs(GET_METHODS) do
	GenerateWithHandler(GenerateGetHandler, Method)
end

return ProxyService