include "io.alh"
include "primitives.alh"

// Placeholder for internal functions
Element function __input()
Void function __output(value : Element)

Element function input():
	while (bool_not(has_input())):
		interruptable_sleep(0.5)
	
	Element inp
	inp = __input()
	return inp!

Void function output(value : Element):
	__output(value)
	return!

Element function input_timeout(timeout : Float):
	Float start
	start = time()

	// Do this first, such that we will always get at least the chance to push input in
	if (has_input()):
		return input()!

	// Now just try this again from time to time
	while (time() - start < timeout):
		if (has_input()):
			return input()!
		else:
			// Nothing to do, we should yield...
			interruptable_sleep(0.1)

	return read_root()!

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

Void function give_input_to_other(comm : String, value : Element):
	Element root
	root = read_root()

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

	return!

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

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

	return value!
