extends Node

var autotracker_port = 41253

var _server = WebSocketServer.new()
var _peers = []


func _ready():
	_server.bind_ip = "127.0.0.1"
	_server.connect("client_connected", self, "_connection_established")
	_server.connect("client_disconnected", self, "_connection_dropped")
	_server.connect("data_received", self, "_data_received")
	_server.listen(autotracker_port)


func _process(_delta):
	_server.poll()


func _connection_established(id, _protocol):
	_peers.append(id)

	var apclient = global.get_node("Archipelago")

	var msg = {
		"cmd": "Connect",
		"slot":
		{"server": apclient.ap_server, "player": apclient.ap_user, "password": apclient.ap_pass}
	}

	var peer = _server.get_peer(id)
	peer.set_write_mode(WebSocketPeer.WRITE_MODE_TEXT)
	peer.put_packet(JSON.print(msg).to_utf8())


func _connection_dropped(id, _was_clean_close):
	_peers.erase(id)


func _data_received(id):
	var peer = _server.get_peer(id)
	peer.set_write_mode(WebSocketPeer.WRITE_MODE_TEXT)

	var packet_text = peer.get_packet().get_string_from_utf8()
	global._print("Got data from tracker: " + packet_text)
	var data = JSON.parse(packet_text)
	if data.error != OK:
		global._print("Error parsing packet from Tracker: " + data.error_string)
		return

	var apclient = global.get_node("Archipelago")
	var msg = data.result

	if msg["cmd"] == "Sync":
		var resp = {}

		var panels = []
		var panels_node = self.get_node("../Panels")
		for group in panels_node.get_children():
			for panel in group.get_children():
				if panel.is_complete:
					panels.append("%s/%s" % [group.name, panel.name])
		if !panels.empty():
			resp = {"cmd": "SolvePanels", "panels": panels}

			peer.put_packet(JSON.print(resp).to_utf8())

		if apclient.track_player:
			var player = get_tree().get_root().get_node("Spatial/player")
			resp = {
				"cmd": "UpdatePosition",
				"position": {"x": int(player._oldpos_fine.x), "z": int(player._oldpos_fine.z)}
			}

			peer.put_packet(JSON.print(resp).to_utf8())


func _broadcast(msg):
	var to_remove = []
	var serialized = JSON.print(msg).to_utf8()

	for peer_id in _peers:
		if _server.has_peer(peer_id):
			var peer = _server.get_peer(peer_id)
			peer.set_write_mode(WebSocketPeer.WRITE_MODE_TEXT)
			peer.put_packet(serialized)
		else:
			to_remove.append(peer_id)

	for peer_id in to_remove:
		_peers.erase(peer_id)


func has_connection():
	return _peers.size() > 0


func update_position(x, z):
	_broadcast({"cmd": "UpdatePosition", "position": {"x": x, "z": z}})


func solve_panel(name):
	_broadcast({"cmd": "SolvePanels", "panels": [name]})