include "primitives.alh"
include "utils.alh"
include "core_algorithm.alh"
include "modelling.alh"
include "object_operations.alh"

Integer services = 0

String function comm_newPort():
	// Create a new username, though prefixed with __ to prevent execution: this is merely a communication port!
	// The specified port needs an input and output queue, like ordinary users.
	Element root
	root = read_root()

	// Initialize, but we know that __hierarchy is already taken!
	String attempt
	attempt = "__hierarchy"
	while (dict_in(root, attempt)):
		attempt = "__" + get_taskname() + "_" + cast_value(services)
		services = services + 1

	// Create queues
	Element queues
	queues = dict_create()
	dict_add(queues, "input", create_node())
	dict_add(queues, "last_input", queues["input"])
	dict_add(queues, "output", create_node())
	dict_add(queues, "last_output", queues["output"])

	// Make it visible
	dict_add(root, attempt, queues)
	return attempt!

Boolean function comm_hasInput(comm : String):
	// Check if there is any input on the specified pseudo-username
	Element root
	root = read_root()
	return dict_in(root[comm]["input"], "value")!

Void function comm_set(comm : String, value : Element):
	// Set input to the specified service
	// For the Mv, this is actually output!
	Element root
	root = read_root()

	Element new
	new = create_node()
	dict_add(root[comm]["last_output"], "value", value)
	dict_add(root[comm]["last_output"], "next", new)
	dict_overwrite(root[comm], "last_output", new)

	return!

Element function comm_get(comm : String):
	// Fetch input from the service
	while (bool_not(comm_hasInput(comm))):
		sleep(0.1)

	// Return the value that we got
	Element root
	Element value
	root = read_root()
	value = root[comm]["input"]["value"]
	dict_overwrite(root[comm], "input", root[comm]["input"]["next"])

	return value!

String function comm_connect(service : String):
	// Connect to an existing service
	service = get_service_id(service)

	if (service == ""):
		return ""!

	service = read_attribute(core, service, "port")

	String port
	port = comm_newPort()
	comm_set(service, port)
	return port!

Void function comm_close(comm : String):
	if (string_startswith(comm, "__")):
		dict_delete(read_root(), comm)
	return!

Element function comm_get_list(comm : String):
	Integer length
	Element result

	length = comm_get(comm)
	result = list_create()
	while (length > 0):
		list_append(result, comm_get(comm))
		length = length - 1

	return result!
