//
//  message_splitter.h
//  Tightbeam

#ifndef TIGHTBEAM_MESSAGE_SPLITTER_H
#define TIGHTBEAM_MESSAGE_SPLITTER_H

#include <Tightbeam/tightbeam.h>

TB_ASSUME_NONNULL_BEGIN
__TB_BEGIN_DECLS

// A layer for splitting up large messages and sending them over multiple IPC
// transmissions.
//
// This system is generic and can be used by any transport that configures it.

/// Indicates whether a message of the requested size would need splitting over multiple IPC transactions
/// using the provided transport.
///
/// @param transport
/// The transport the query will be sent using.
///
/// @param message_size
/// The message size in bytes.
///
/// @return True if the message needs to be split otherwise false.
TB_EXPORT
bool
tb_message_splitter_split_required(tb_transport_t transport,
        size_t message_size);

/// Send a large message by splitting it across mutiple IPC sends.
///
/// @param transport
/// The transport that will send the message.
///
/// @param query
/// The query message to send.
///
/// @param reply
/// A pointer that will be assigned to point to any reply that is received.
///
/// @param flags
/// Flags that are sent to the transport when sending the query.
///
/// @return An appropriate error if it occurs, otherwise success.
TB_EXPORT
tb_error_t
tb_message_splitter_send(struct tb_connection_s *conn, tb_transport_t transport,
        tb_message_t query, tb_message_t _Nullable * _Nullable reply,
        tb_connection_flags_t flags);

/// Add a reply message to the list of replies in-flight. This allows the replies to be split across multiple IPC
/// transactions.
///
/// @param reply_list
/// The reply list to add the reply to.
///
/// @param message
/// The reply message to be split.
///
/// @param first_response
/// A pointer to a message that will be assigned to point to the first part of the reply.
///
/// @param service_connection
/// The Service Connection that will be used to send the reply message.
///
/// @return An appropriate error if it occurs, otherwise success.
TB_EXPORT
tb_error_t
tb_reply_splitter_add_reply(tb_list_t reply_list, tb_message_t message,
        tb_message_t _Nonnull * _Nullable first_response,
        tb_service_connection_t service_connection);

/// Given a request message get the next reply message in a series for a large reply.
///
/// @param reply_list
/// The list to retrieve the next reply part from.
///
/// @param query
/// The client query for the next reply message.
///
/// @param message
/// A pointer to a message that will be assigned to point to the next part of the reply.
///
/// @param transport
/// The transport that will be used to send the reply message.
///
/// @return An appropriate error if it occurs, otherwise success.
TB_EXPORT
tb_error_t
tb_reply_splitter_next_message(tb_list_t reply_list,
        struct tb_connection_s *conn, tb_message_t query,
        tb_message_t _Nonnull * _Nullable message, tb_transport_t transport);

__TB_END_DECLS
TB_ASSUME_NONNULL_END

#endif /* TIGHTBEAM_MESSAGE_SPLITTER_H */
