//
//  tb_forwarding_connection.h
//  Tightbeam

#ifndef __TIGHTBEAM_FORWARDING_CONNECTION_H
#define __TIGHTBEAM_FORWARDING_CONNECTION_H

#include <sys/cdefs.h>
__ptrcheck_abi_assume_single()

#include <stdbool.h>
#include <Tightbeam/tightbeam.h>
#include <Tightbeam/tb_transport.h>

TB_ASSUME_NONNULL_BEGIN
__TB_BEGIN_DECLS

struct tb_forwarding_connection_s;
typedef struct tb_forwarding_connection_s * __single tb_forwarding_connection_t
        __TB_WARN_UNUSED_RESULT;

/// Returns whether the specified message should be forwarded.
typedef bool (^tb_forwarding_message_handler_b)(
        tb_forwarding_connection_t connection, const tb_message_t _Nonnull msg,
        bool outgoing);

/// Construct a new forward connection object using two endpoints, one for
/// receiving Tightbeam messages, and another for sending Tightbeam messages.
/// The receive endpoint will appear as a server connection, and the sending
/// endpoint will appear as a client connection.
///
/// @param endpoint_server
/// The endpoint to receive messages from.
///
/// @param endpoint_client
/// The endpoint to send messages to.
///
/// @discussion
/// The endpoint must wrap the resources needed to bootstrap the specified 
/// transport type. This will assert on failure.
TB_EXPORT
tb_forwarding_connection_t
tb_forwarding_connection_create_with_endpoint(tb_endpoint_t endpoint_server,
        tb_endpoint_t endpoint_client, tb_forwarding_message_handler_b handler);

/// Construct a new forward connection object that can be used to send/receive
/// Tightbeam messages.
/// The receive endpoint will appear as a server connection, and the sending
/// endpoint will appear as a client connection.
///
/// @param transport_receive
/// The transport to receive messages from.
///
/// @param transport_send
/// The transport to send messages to.
///
/// @return
/// A Tightbeam Connection instance that can be used to send and receive
/// Tightbeam messages.
TB_EXPORT
tb_forwarding_connection_t
tb_forwarding_connection_create(tb_transport_t transport_receive,
        tb_transport_t transport_send, tb_forwarding_message_handler_b handler);

/// Activate a forward connection. This should be called when all connection 
/// configuration is complete.
///
/// @param connection
/// The forward connection to activate.
///
/// @return
/// On success returns `TB_ERROR_SUCCESS`, or a code indicating an error 
/// occurred.
TB_EXPORT
tb_error_t
tb_forwarding_connection_activate(tb_forwarding_connection_t connection);

/// Destruct a forwarding connection
///
/// @param connection
/// The forwarding Tightbeam connection created with 
/// tb_forwarding_connection_create
TB_EXPORT
void
tb_forwarding_connection_destruct(tb_forwarding_connection_t connection);

__TB_END_DECLS
TB_ASSUME_NONNULL_END

#endif // __TIGHTBEAM_FORWARDING_CONNECTION_H
