extends Node

var SERVER_TO_SERVER_PORT = 54671
var MATCHMAKING_PORT = 54672
var GAME_SIZE = 6
# Number of games we can make without blowing up the computer
var MAX_GAMES = 50 # Based on how many ports I decided to forward

var next_port = 54673

# Filled with queue info which contains
# { "netid" }
var skirmishing_players = []
var skirmish
# To avoid the confusion of the gameSERVERS being CLIENTS,
# we just call them games whenever possible
# var games = []
var game_connections = []
var game_streams = []

# Matchmaker to game servers
var matchmaker_to_games

enum messages {
	ready_to_connect,
}

onready var lobby = get_node("..")

func _ready():
	# By default, having this node doesn't do naything
	# You must call start_matchmaker to enable it
	# If not called, don't call _process (= don't matchmake)
	set_process(false)

func start_matchmaker():
	# Actually run the matchmaker
	set_process(true)

	# Setup skirmish server
	skirmish = spawn_server(true)

	# Set up communication between GAMESERVERS
	# This is necessary for eg, when a player leaves to backfill
	matchmaker_to_games = TCP_Server.new()
	if matchmaker_to_games.listen(SERVER_TO_SERVER_PORT):
		print("Error, could not listen")

	# Use ENet for matchmaker because we can (makes client code cleaner)
	var matchmaker_to_players = NetworkedMultiplayerENet.new()
	print("Starting matchmaker on port " + str(MATCHMAKING_PORT))
	matchmaker_to_players.create_server(MATCHMAKING_PORT, MAX_GAMES)
	get_tree().set_network_peer(matchmaker_to_players)
	matchmaker_to_players.connect("peer_connected", self, "queue")

func _process(delta):
	# Manage connection to GAMESERVERS (not clients)
	if matchmaker_to_games.is_connection_available(): # check if a gameserver's trying to connect
		var game = matchmaker_to_games.take_connection() # accept connection
		game_connections.append(game) # store the connection
		var stream = PacketPeerStream.new()
		stream.set_stream_peer(game) # bind peerstream to new client
		game_streams.append(stream) # make new data transfer object for game
	for stream in game_streams:
		if stream.get_available_packet_count():
			var message = stream.get_var()
			if message == messages.ready_to_connect:
				var port = stream.get_var()
				print("Server " + str(port) + " has requested connection")
				skirmish_to_game(port, GAME_SIZE)

func queue(netid):
	print("Player " + str(netid) + " connected.")
	add_to_game(netid, skirmish)
	skirmishing_players.append(netid)
	check_queue()

func add_to_game(netid, port):
	networking.rpc_id(netid, "reconnect", networking.global_server_ip, port)

func skirmish_to_game(port, count=1):
	for i in range(count):
		if not skirmishing_players.size():
			return false
		print(skirmishing_players[0])
		print("to")
		print(port)
		add_to_game(skirmishing_players[0], port)
	return true

func check_queue():
	# Prefer making a full game to backfilling
	if skirmishing_players.size() >= GAME_SIZE:
		spawn_server()
		# games.append(port)

func spawn_server(skirmish=false):
	var args = ['-port='+str(next_port)]
	if skirmish:
		# Begin skirmish immediately, so players "join" instead of "ready"
		args.append("-start-game")
	OS.execute("util/server.sh", args, false)
	next_port += 1
	return (next_port - 1) # Return original port

