<commit_before>#ifndef CTHUN_CLIENT_SRC_CONNECTOR_CONNECTOR_H_
#define CTHUN_CLIENT_SRC_CONNECTOR_CONNECTOR_H_

#include <cthun-client/connector/connection.hpp>
#include <cthun-client/connector/client_metadata.hpp>
#include <cthun-client/connector/errors.hpp>
#include <cthun-client/validator/validator.hpp>
#include <cthun-client/validator/schema.hpp>
#include <cthun-client/protocol/chunks.hpp>
#include <cthun-client/protocol/message.hpp>

#include <memory>
#include <string>
#include <map>
#include <thread>  // mutex
#include <condition_variable>
#include <atomic>

namespace CthunClient {

//
// Connector
//
namespace LTH_JC = leatherman::json_container;

class Connector {
  public:
    using MessageCallback = std::function<void(const ParsedChunks& parsed_chunks)>;

    Connector() = delete;

    /// Throws a connection_config_error in case it fails to retrieve
    /// the client identity from its certificate.
    Connector(const std::string& server_url,
              const std::string& client_type,
              const std::string& ca_crt_path,
              const std::string& client_crt_path,
              const std::string& client_key_path);

    ~Connector();

    /// Throw a schema_redefinition_error if the specified schema has
    /// been already registred.
    void registerMessageCallback(const Schema schema,
                                 MessageCallback callback);

    /// Set an optional callback for error messages
    void setCthunErrorCallback(MessageCallback callback);

    /// Set an optional callback for associate responses
    void setAssociateCallback(MessageCallback callback);

    /// Check the state of the underlying connection (WebSocket); in
    /// case it's not open, try to re-open it.
    /// Try to reopen for max_connect_attempts times or idefinetely,
    /// in case that parameter is 0 (as by default). This is done by
    /// following an exponential backoff.
    /// Once the underlying connection is open, send an associate
    /// session request to the server.
    /// Throw a connection_config_error if it fails to set up the
    /// underlying communications layer (ex. invalid certificates).
    /// Throw a connection_fatal_error if it fails to open the
    /// underlying connection after the specified number of attempts
    /// or if it fails to send the associate session request.
    /// NB: the function does not wait for the associate response; it
    ///     returns right after sending the associate request
    /// NB: the function is not thread safe
    void connect(int max_connect_attempts = 0);

    /// Returns true if the underlying connection is currently open,
    /// false otherwise.
    bool isConnected() const;

    /// Returns true if a successful associate response has been
    /// received and the underlying connection did not drop since
    /// then, false otherwise.
    bool isAssociated() const;

    /// Periodically check the state of the underlying connection.
    /// Re-establish the connection in case it has dropped, otherwise
    /// send a ping mst to the server in order to keep the connection
    /// alive.
    /// The max_connect_attempts parameters is used to reconnect; it
    /// works as for the above connect() function.
    ///
    /// Note that this is a blocking call; this task will not be
    /// executed in a separate thread.
    /// Also, monitorConnection simply returns in case of multiple
    /// calls.
    ///
    /// It is safe to call monitorConnection in a multithreading
    /// context; it will return as soon as the dtor has been invoked.
    ///
    /// Throw a connection_fatal_error if, in case of dropped
    /// underlying connection, it fails to re-connect after the
    /// specified maximum number of attempts.
    /// Throws a connection_not_init_error in case the connection has
    /// not been opened previously.
    void monitorConnection(int max_connect_attempts = 0);

    /// Send a message.
    /// Throw a connection_processing_error in case of failure.
    /// Throw a connection_not_init_error in case the connection has
    /// not been opened previously.
    void send(const Message& msg);

    void send(const std::vector<std::string>& targets,
              const std::string& message_type,
              unsigned int timeout,
              const LTH_JC::JsonContainer& data_json,
              const std::vector<LTH_JC::JsonContainer>& debug = std::vector<LTH_JC::JsonContainer> {});

    void send(const std::vector<std::string>& targets,
              const std::string& message_type,
              unsigned int timeout,
              const std::string& data_binary,
              const std::vector<LTH_JC::JsonContainer>& debug = std::vector<LTH_JC::JsonContainer> {});

    void send(const std::vector<std::string>& targets,
              const std::string& message_type,
              unsigned int timeout,
              bool destination_report,<commit_msg>(maint) Improve documentation of Connector::send()<commit_after>#ifndef CTHUN_CLIENT_SRC_CONNECTOR_CONNECTOR_H_
#define CTHUN_CLIENT_SRC_CONNECTOR_CONNECTOR_H_

#include <cthun-client/connector/connection.hpp>
#include <cthun-client/connector/client_metadata.hpp>
#include <cthun-client/connector/errors.hpp>
#include <cthun-client/validator/validator.hpp>
#include <cthun-client/validator/schema.hpp>
#include <cthun-client/protocol/chunks.hpp>
#include <cthun-client/protocol/message.hpp>

#include <memory>
#include <string>
#include <map>
#include <thread>  // mutex
#include <condition_variable>
#include <atomic>

namespace CthunClient {

//
// Connector
//
namespace LTH_JC = leatherman::json_container;

class Connector {
  public:
    using MessageCallback = std::function<void(const ParsedChunks& parsed_chunks)>;

    Connector() = delete;

    /// Throws a connection_config_error in case it fails to retrieve
    /// the client identity from its certificate.
    Connector(const std::string& server_url,
              const std::string& client_type,
              const std::string& ca_crt_path,
              const std::string& client_crt_path,
              const std::string& client_key_path);

    ~Connector();

    /// Throw a schema_redefinition_error if the specified schema has
    /// been already registred.
    void registerMessageCallback(const Schema schema,
                                 MessageCallback callback);

    /// Set an optional callback for error messages
    void setCthunErrorCallback(MessageCallback callback);

    /// Set an optional callback for associate responses
    void setAssociateCallback(MessageCallback callback);

    /// Check the state of the underlying connection (WebSocket); in
    /// case it's not open, try to re-open it.
    /// Try to reopen for max_connect_attempts times or idefinetely,
    /// in case that parameter is 0 (as by default). This is done by
    /// following an exponential backoff.
    /// Once the underlying connection is open, send an associate
    /// session request to the server.
    /// Throw a connection_config_error if it fails to set up the
    /// underlying communications layer (ex. invalid certificates).
    /// Throw a connection_fatal_error if it fails to open the
    /// underlying connection after the specified number of attempts
    /// or if it fails to send the associate session request.
    /// NB: the function does not wait for the associate response; it
    ///     returns right after sending the associate request
    /// NB: the function is not thread safe
    void connect(int max_connect_attempts = 0);

    /// Returns true if the underlying connection is currently open,
    /// false otherwise.
    bool isConnected() const;

    /// Returns true if a successful associate response has been
    /// received and the underlying connection did not drop since
    /// then, false otherwise.
    bool isAssociated() const;

    /// Periodically check the state of the underlying connection.
    /// Re-establish the connection in case it has dropped, otherwise
    /// send a ping mst to the server in order to keep the connection
    /// alive.
    /// The max_connect_attempts parameters is used to reconnect; it
    /// works as for the above connect() function.
    ///
    /// Note that this is a blocking call; this task will not be
    /// executed in a separate thread.
    /// Also, monitorConnection simply returns in case of multiple
    /// calls.
    ///
    /// It is safe to call monitorConnection in a multithreading
    /// context; it will return as soon as the dtor has been invoked.
    ///
    /// Throw a connection_fatal_error if, in case of dropped
    /// underlying connection, it fails to re-connect after the
    /// specified maximum number of attempts.
    /// Throws a connection_not_init_error in case the connection has
    /// not been opened previously.
    void monitorConnection(int max_connect_attempts = 0);

    /// Send the specified message.
    ///
    /// Other overloads may specify:
    ///   - targets: list of Cthun URI strings
    ///   - message_type: schema name that identifies the message type
    ///   - timeout: expires entry in seconds
    ///   - destination_report: bool; the client must flag it in case
    ///     he wants to receive a destination report from the server
    ///   - data: in binary (string)
    ///
    /// All methods:
    ///   - throw a connection_processing_error in case of failure;
    ///   - throw a connection_not_init_error in case the connection
    ///     has not been opened previously.
    void send(const Message& msg);

    void send(const std::vector<std::string>& targets,
              const std::string& message_type,
              unsigned int timeout,
              const LTH_JC::JsonContainer& data_json,
              const std::vector<LTH_JC::JsonContainer>& debug = std::vector<LTH_JC::JsonContainer> {});

    void send(const std::vector<std::string>& targets,
              const std::string& message_type,
              unsigned int timeout,
              const std::string& data_binary,
              const std::vector<LTH_JC::JsonContainer>& debug = std::vector<LTH_JC::JsonContainer> {});

    void send(const std::vector<std::string>& targets,
              const std::string& message_type,
              unsigned int timeout,
              bool destination_report,
{'fraction_non_alphanumeric': 0.0905744454131551, 'fraction_numerical': 0.0005812263876780006, 'mean_word_length': 2.763762304046664, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2002118', 'n_tokens_mistral': 2710, 'n_tokens_neox': 2639, 'n_words': 1018}