#pragma once

/**
** \defgroup packetstream Packet Stream
** Primitive helper for sending packets of known size across a pipe.
** @{
*/

#include <stddef.h>

/** A handle to a UNIX-style pipe. */
typedef struct uv_pipe_s uv_pipe_t;

/** A packet stream instance. */
typedef struct _tf_packetstream_t tf_packetstream_t;

/**
** A function called when a packet is received.
** @param packet_type The type of the packet as specified by the sender.
** @param begin The beginning of the data.
** @param length The length of the data.
** @param user_data User data.
*/
typedef void(tf_packetstream_onreceive_t)(int packet_type, const char* begin, size_t length, void* user_data);

/**
** A function called when a packetstream reads EOF.
** @param user_data User data.
*/
typedef void(tf_packetstream_on_close_t)(void* user_data);

/**
** Create a packet stream.
** @return The packet stream.
*/
tf_packetstream_t* tf_packetstream_create();

/**
** Destroy a packet stream.
** @param stream The packet stream.
*/
void tf_packetstream_destroy(tf_packetstream_t* stream);

/**
** Start a packet stream receiving.
** @param stream The packet stream.
*/
void tf_packetstream_start(tf_packetstream_t* stream);

/**
** Send a discrete packet over a packet stream.
** @param stream The packet stream.
** @param packet_type The type of the packet.
** @param begin The start of the packet data.
** @param length The length of the packet data.
*/
void tf_packetstream_send(tf_packetstream_t* stream, int packet_type, const char* begin, size_t length);

/**
** Register the callback to be called when a message is received.
** @param stream The packet stream.
** @param callback The callback function.
** @param user_data User data to pass to the callback.
*/
void tf_packetstream_set_on_receive(tf_packetstream_t* stream, tf_packetstream_onreceive_t* callback, void* user_data);

/**
** Register a callback for when a stream reads EOF.
** @param stream The packet stream.
** @param callback The callback.
** @param user_data User data to pass to the callback.
*/
void tf_packetstream_set_on_close(tf_packetstream_t* stream, tf_packetstream_on_close_t* callback, void* user_data);

/**
** Close a packet stream.
** @param stream The packet stream.
*/
void tf_packetstream_close(tf_packetstream_t* stream);

/**
** Get the internal pipe object from a packet stream.
** @param stream The packet stream.
** @return The pipe.
*/
uv_pipe_t* tf_packetstream_get_pipe(tf_packetstream_t* stream);

/** @} */
