extends Node
class_name HttpClient

signal request_completed(type: API_TYPE, data: Dictionary)

const API_URL = "https://api.twitch.tv/helix"

enum API_TYPE {
	AUTH,
	CREATE_EVENTSUB,
	VERIFY,
	SEND_CHAT_MESSAGE,
	SHOUTOUT,
	USERS,
	EMOTE
}

var auth

func send_message(message: String):
	var parent = get_parent()
	
	request(API_TYPE.SEND_CHAT_MESSAGE, {}, {
		"broadcaster_id": parent.auth.BROADCASTER_ID,
		"sender_id": parent.auth.USER_ID,
		"message": message
	})

func request(type: API_TYPE, arguments: Dictionary = {}, data: Dictionary = {}):
	var path = _get_path_from_type(type, arguments)
	var headers = _get_headers_from_type(type)
	var method = HTTPClient.METHOD_POST
	
	if type == API_TYPE.VERIFY:
		headers.push_back("Authorization: OAuth %s" % arguments.token)
		auth = arguments.token
		method = HTTPClient.METHOD_GET
	if type == API_TYPE.USERS:
		method = HTTPClient.METHOD_GET
	if type == API_TYPE.EMOTE:
		method = HTTPClient.METHOD_GET
	
	var request = HTTPRequest.new()
	add_child(request)
	#prints(path, headers, method, JSON.stringify(data))
	if method == HTTPClient.METHOD_GET:
		request.request(path, headers, method)
	else:
		request.request(path, headers, method, JSON.stringify(data))
	request.request_completed.connect(_on_request_completed.bind(type))
	
	var response = await request.request_completed
	
	if response[2].has("Content-Type: image/png"):
		return response[3]
	
	var string = ""
	for character in response[3]:
		string += char(character)
	
	var json = JSON.parse_string(string)
	
	return json


func _on_request_completed(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray, type: API_TYPE):
	var string = ""
	for character in body:
		string += char(character)
	
	if headers.has("Content-Type: application/json"):
		var json = JSON.parse_string(string)
		
		request_completed.emit(type, json)

func _get_path_from_type(type: API_TYPE, arguments: Dictionary):
	var comp_args = ""
	
	for argument in arguments:
		if comp_args == "":
			comp_args += "?%s=%s" % [argument, arguments[argument]]
		else:
			comp_args += "&%s=%s" % [argument, arguments[argument]]
	
	match type:
		API_TYPE.AUTH:
			return "https://id.twitch.tv/oauth2/token" + comp_args
		API_TYPE.CREATE_EVENTSUB:
			return "%s/eventsub/subscriptions" % [API_URL]
		API_TYPE.VERIFY:
			return "https://id.twitch.tv/oauth2/validate"
		API_TYPE.SEND_CHAT_MESSAGE:
			return "%s/chat/messages" % [API_URL] + comp_args
		API_TYPE.USERS:
			return "%s/users"  % [API_URL] + comp_args
		API_TYPE.SHOUTOUT:
			return "%s/chat/shoutouts" % [API_URL] + comp_args
		API_TYPE.EMOTE:
			return "https://static-cdn.jtvnw.net/emoticons/v2/%s/static/dark/1.0" % [arguments.id]


func _get_headers_from_type(type: API_TYPE):
	match type:
		API_TYPE.AUTH:
			return []
		API_TYPE.VERIFY:
			return []
		_:
			return [_get_bearer(), _get_client_id(), "Content-Type: application/json"]


func _get_bearer():
	return "Authorization: Bearer %s" % [auth]


func _get_client_id():
	var parent = get_parent()
	return "Client-Id: %s" % [parent.auth.CLIENT_ID]