/*
 * HDDS C FFI Bindings
 * Auto-generated by cbindgen - DO NOT EDIT
 *
 * This header provides C-compatible bindings for the HDDS DDS implementation.
 */


#ifndef HDDS_H
#define HDDS_H

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
/* ROS2 RMW support - only include if building with ROS2 */
#ifdef HDDS_WITH_ROS2
#include <rosidl_runtime_c/message_type_support_struct.h>
#include <rosidl_runtime_c/string.h>
#include <rosidl_runtime_c/u16string.h>
#else
/* Standalone fallback definitions when not building with ROS 2 */
typedef struct rosidl_runtime_c__String {
  char *data;
  size_t size;
  size_t capacity;
} rosidl_runtime_c__String;
typedef struct rosidl_runtime_c__U16String {
  uint16_t *data;
  size_t size;
  size_t capacity;
} rosidl_runtime_c__U16String;
typedef struct rosidl_message_type_support_t rosidl_message_type_support_t;
#endif


/**
 * Error codes (C-compatible enum)
 *
 * # Error Code Categories
 *
 * - **0-9**: Success and generic errors
 * - **10-19**: Configuration errors
 * - **20-29**: I/O and transport errors
 * - **30-39**: Type and serialization errors
 * - **40-49**: QoS and resource errors
 * - **50-59**: Security errors
 */
typedef enum HddsError {
  /**
   * Operation completed successfully
   */
  HDDS_OK = 0,
  /**
   * Invalid argument provided (null pointer, invalid value)
   */
  HDDS_INVALID_ARGUMENT = 1,
  /**
   * Requested resource not found
   */
  HDDS_NOT_FOUND = 2,
  /**
   * Generic operation failure
   */
  HDDS_OPERATION_FAILED = 3,
  /**
   * Memory allocation failed
   */
  HDDS_OUT_OF_MEMORY = 4,
  /**
   * Invalid configuration settings
   */
  HDDS_CONFIG_ERROR = 10,
  /**
   * Invalid domain ID (must be 0-232)
   */
  HDDS_INVALID_DOMAIN_ID = 11,
  /**
   * Invalid participant ID (must be 0-119)
   */
  HDDS_INVALID_PARTICIPANT_ID = 12,
  /**
   * No available participant ID (all 120 ports occupied)
   */
  HDDS_NO_AVAILABLE_PARTICIPANT_ID = 13,
  /**
   * Invalid entity state for requested operation
   */
  HDDS_INVALID_STATE = 14,
  /**
   * Generic I/O error
   */
  HDDS_IO_ERROR = 20,
  /**
   * UDP transport send/receive failed
   */
  HDDS_TRANSPORT_ERROR = 21,
  /**
   * Topic registration failed
   */
  HDDS_REGISTRATION_FAILED = 22,
  /**
   * Operation would block but non-blocking mode requested
   */
  HDDS_WOULD_BLOCK = 23,
  /**
   * Type mismatch between writer and reader
   */
  HDDS_TYPE_MISMATCH = 30,
  /**
   * CDR serialization failed
   */
  HDDS_SERIALIZATION_ERROR = 31,
  /**
   * Buffer too small for encoding
   */
  HDDS_BUFFER_TOO_SMALL = 32,
  /**
   * CDR endianness mismatch
   */
  HDDS_ENDIAN_MISMATCH = 33,
  /**
   * QoS policies are incompatible between endpoints
   */
  HDDS_QOS_INCOMPATIBLE = 40,
  /**
   * Requested feature or operation is not supported
   */
  HDDS_UNSUPPORTED = 41,
  /**
   * Permission denied by access control (DDS Security)
   */
  HDDS_PERMISSION_DENIED = 50,
  /**
   * Authentication failed
   */
  HDDS_AUTHENTICATION_FAILED = 51,
} HddsError;

/**
 * Liveliness kind enumeration for C FFI.
 */
typedef enum HddsLivelinessKind {
  /**
   * DDS infrastructure automatically asserts liveliness.
   */
  HDDS_LIVELINESS_AUTOMATIC = 0,
  /**
   * Application must assert per participant.
   */
  HDDS_LIVELINESS_MANUAL_BY_PARTICIPANT = 1,
  /**
   * Application must assert per writer/topic.
   */
  HDDS_LIVELINESS_MANUAL_BY_TOPIC = 2,
} HddsLivelinessKind;

/**
 * Log level for HDDS logging
 */
typedef enum HddsLogLevel {
  HDDS_LOG_OFF = 0,
  HDDS_LOG_ERROR = 1,
  HDDS_LOG_WARN = 2,
  HDDS_LOG_INFO = 3,
  HDDS_LOG_DEBUG = 4,
  HDDS_LOG_TRACE = 5,
} HddsLogLevel;

/**
 * Shared memory policy for C FFI.
 */
typedef enum HddsShmPolicy {
  /**
   * Prefer SHM when available, fallback to UDP (default).
   */
  HDDS_SHM_PREFER = 0,
  /**
   * Require SHM, fail if conditions not met.
   */
  HDDS_SHM_REQUIRE = 1,
  /**
   * Disable SHM, always use network transport.
   */
  HDDS_SHM_DISABLE = 2,
} HddsShmPolicy;

/**
 * TCP role for C FFI.
 */
typedef enum HddsTcpRole {
  /**
   * Auto-negotiation via GUID tie-breaker (default).
   */
  HDDS_TCP_ROLE_AUTO = 0,
  /**
   * Server only: listen but never initiate.
   */
  HDDS_TCP_ROLE_SERVER_ONLY = 1,
  /**
   * Client only: initiate but never listen.
   */
  HDDS_TCP_ROLE_CLIENT_ONLY = 2,
} HddsTcpRole;

/**
 * Transport mode for participant creation
 */
typedef enum HddsTransportMode {
  /**
   * Intra-process only (no network, fastest for same-process communication)
   */
  HDDS_TRANSPORT_INTRA_PROCESS = 0,
  /**
   * UDP multicast for network discovery and communication (default for DDS interop)
   */
  HDDS_TRANSPORT_UDP_MULTICAST = 1,
} HddsTransportMode;

/**
 * Transport preference for C FFI.
 */
typedef enum HddsTransportPreference {
  /**
   * UDP only (default).
   */
  HDDS_TRANSPORT_PREF_UDP_ONLY = 0,
  /**
   * TCP only (requires initial peers).
   */
  HDDS_TRANSPORT_PREF_TCP_ONLY = 1,
  /**
   * UDP for discovery, TCP for data.
   */
  HDDS_TRANSPORT_PREF_UDP_DISCOVERY_TCP_DATA = 2,
  /**
   * Prefer SHM for local, UDP for remote.
   */
  HDDS_TRANSPORT_PREF_SHM_PREFERRED = 3,
  /**
   * SHM for local, TCP for remote.
   */
  HDDS_TRANSPORT_PREF_SHM_LOCAL_TCP_REMOTE = 4,
} HddsTransportPreference;

typedef struct Option_HddsLocatorVisitor Option_HddsLocatorVisitor;

typedef struct Option_HddsTopicVisitor Option_HddsTopicVisitor;

/**
 * Opaque handle to a Participant
 */
typedef struct HddsParticipant {
  uint8_t PRIVATE[0];
} HddsParticipant;

/**
 * Opaque handle to a GuardCondition
 */
typedef struct HddsGuardCondition {
  uint8_t PRIVATE[0];
} HddsGuardCondition;

typedef struct HddsTypeObject {
  uint8_t PRIVATE[0];
} HddsTypeObject;

/**
 * Opaque handle to a `DataWriter`
 */
typedef struct HddsDataWriter {
  uint8_t PRIVATE[0];
} HddsDataWriter;

/**
 * Opaque handle to a QoS profile.
 */
typedef struct HddsQoS {
  uint8_t PRIVATE[0];
} HddsQoS;

/**
 * Opaque handle to a `DataReader`
 */
typedef struct HddsDataReader {
  uint8_t PRIVATE[0];
} HddsDataReader;

/**
 * Opaque handle to a StatusCondition
 */
typedef struct HddsStatusCondition {
  uint8_t PRIVATE[0];
} HddsStatusCondition;

/**
 * Opaque handle to a WaitSet
 */
typedef struct HddsWaitSet {
  uint8_t PRIVATE[0];
} HddsWaitSet;

#if defined(HDDS_WITH_ROS2)
/**
 * Opaque handle to an rmw context
 */
typedef struct HddsRmwContext {
  uint8_t PRIVATE[0];
} HddsRmwContext;
#endif

#if defined(HDDS_WITH_ROS2)
typedef struct HddsRmwQosProfile {
  uint8_t HISTORY;
  uint32_t DEPTH;
  uint8_t RELIABILITY;
  uint8_t DURABILITY;
  uint64_t DEADLINE_NS;
  uint64_t LIFESPAN_NS;
  uint8_t LIVELINESS;
  uint64_t LIVELINESS_LEASE_NS;
  bool AVOID_ROS_NAMESPACE_CONVENTIONS;
} HddsRmwQosProfile;
#endif

#if defined(HDDS_WITH_ROS2)
typedef void (*HddsNodeVisitor)(const char*, const char*, void*);
#endif

#if defined(HDDS_WITH_ROS2)
typedef void (*HddsNodeEnclaveVisitor)(const char*, const char*, const char*, void*);
#endif

#if defined(HDDS_WITH_ROS2)
typedef void (*HddsEndpointVisitor)(const char*,
                                    const char*,
                                    const uint8_t*,
                                    const struct HddsRmwQosProfile*,
                                    void*);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Opaque handle to an rmw waitset
 */
typedef struct HddsRmwWaitSet {
  uint8_t PRIVATE[0];
} HddsRmwWaitSet;
#endif

/**
 * Callback for data available events.
 *
 * # Parameters
 * - `data`: Pointer to serialized sample bytes
 * - `len`: Length of the serialized data in bytes
 * - `user_data`: User-provided context pointer
 */
typedef void (*HddsOnDataAvailable)(const uint8_t *data, uintptr_t len, void *user_data);

/**
 * Subscription matched status (C-compatible mirror of Rust SubscriptionMatchedStatus).
 *
 * Reports the number of publications matched with this reader.
 */
typedef struct HddsSubscriptionMatchedStatus {
  /**
   * Total cumulative count of matched publications.
   */
  uint32_t TOTAL_COUNT;
  /**
   * Change in total_count since last callback.
   */
  int32_t TOTAL_COUNT_CHANGE;
  /**
   * Current number of matched publications.
   */
  uint32_t CURRENT_COUNT;
  /**
   * Change in current_count since last callback.
   */
  int32_t CURRENT_COUNT_CHANGE;
} HddsSubscriptionMatchedStatus;

/**
 * Callback for subscription matched events.
 */
typedef void (*HddsOnSubscriptionMatched)(const struct HddsSubscriptionMatchedStatus *status,
                                          void *user_data);

/**
 * Liveliness changed status (C-compatible mirror of Rust LivelinessChangedStatus).
 *
 * Reports changes in liveliness of matched writers.
 */
typedef struct HddsLivelinessChangedStatus {
  /**
   * Number of publications currently asserting liveliness.
   */
  uint32_t ALIVE_COUNT;
  /**
   * Change in alive_count since last callback.
   */
  int32_t ALIVE_COUNT_CHANGE;
  /**
   * Number of publications that have lost liveliness.
   */
  uint32_t NOT_ALIVE_COUNT;
  /**
   * Change in not_alive_count since last callback.
   */
  int32_t NOT_ALIVE_COUNT_CHANGE;
} HddsLivelinessChangedStatus;

/**
 * Callback for liveliness changed events.
 */
typedef void (*HddsOnLivelinessChanged)(const struct HddsLivelinessChangedStatus *status,
                                        void *user_data);

/**
 * Sample lost status (C-compatible mirror of Rust SampleLostStatus).
 *
 * Reports samples lost due to gaps in sequence numbers.
 */
typedef struct HddsSampleLostStatus {
  /**
   * Total cumulative count of lost samples.
   */
  uint32_t TOTAL_COUNT;
  /**
   * Change in total_count since last callback.
   */
  int32_t TOTAL_COUNT_CHANGE;
} HddsSampleLostStatus;

/**
 * Callback for sample lost events.
 */
typedef void (*HddsOnSampleLost)(const struct HddsSampleLostStatus *status, void *user_data);

/**
 * Sample rejected status (C-compatible mirror of Rust SampleRejectedStatus).
 *
 * Reports samples rejected due to resource limits.
 * `last_reason` values: 0=NotRejected, 1=ResourceLimit, 2=InstanceLimit,
 * 3=SamplesPerInstanceLimit.
 */
typedef struct HddsSampleRejectedStatus {
  /**
   * Total cumulative count of rejected samples.
   */
  uint32_t TOTAL_COUNT;
  /**
   * Change in total_count since last callback.
   */
  int32_t TOTAL_COUNT_CHANGE;
  /**
   * Reason for rejection (0=NotRejected, 1=ResourceLimit, 2=InstanceLimit, 3=SamplesPerInstanceLimit).
   */
  uint32_t LAST_REASON;
} HddsSampleRejectedStatus;

/**
 * Callback for sample rejected events.
 */
typedef void (*HddsOnSampleRejected)(const struct HddsSampleRejectedStatus *status, void *user_data);

/**
 * Deadline missed status (C-compatible mirror of Rust RequestedDeadlineMissedStatus).
 *
 * Reports missed deadlines on a reader or writer.
 */
typedef struct HddsDeadlineMissedStatus {
  /**
   * Total cumulative count of missed deadlines.
   */
  uint32_t TOTAL_COUNT;
  /**
   * Change in total_count since last callback.
   */
  int32_t TOTAL_COUNT_CHANGE;
} HddsDeadlineMissedStatus;

/**
 * Callback for deadline missed events (reader side).
 */
typedef void (*HddsOnDeadlineMissed)(const struct HddsDeadlineMissedStatus *status, void *user_data);

/**
 * Incompatible QoS status (C-compatible mirror of Rust RequestedIncompatibleQosStatus).
 *
 * Reports QoS incompatibility between matched endpoints.
 */
typedef struct HddsIncompatibleQosStatus {
  /**
   * Total cumulative count of incompatible QoS offers.
   */
  uint32_t TOTAL_COUNT;
  /**
   * Change in total_count since last callback.
   */
  int32_t TOTAL_COUNT_CHANGE;
  /**
   * ID of the last incompatible QoS policy.
   */
  uint32_t LAST_POLICY_ID;
} HddsIncompatibleQosStatus;

/**
 * Callback for incompatible QoS events (reader side).
 */
typedef void (*HddsOnIncompatibleQos)(const struct HddsIncompatibleQosStatus *status,
                                      void *user_data);

/**
 * C-compatible DataReader listener.
 *
 * Set callback fields to receive events. Any callback set to `None` (NULL)
 * will be silently ignored. The `user_data` pointer is passed through to
 * every callback invocation.
 *
 * # Example (C)
 *
 * ```c
 * HddsReaderListener listener = {0};
 * listener.on_data_available = my_data_callback;
 * listener.on_subscription_matched = my_match_callback;
 * listener.user_data = my_context;
 * hdds_reader_set_listener(reader, &listener);
 * ```
 */
typedef struct HddsReaderListener {
  /**
   * Called when new data is available to read.
   */
  HddsOnDataAvailable ON_DATA_AVAILABLE;
  /**
   * Called when the reader matches/unmatches with a writer.
   */
  HddsOnSubscriptionMatched ON_SUBSCRIPTION_MATCHED;
  /**
   * Called when liveliness of a matched writer changes.
   */
  HddsOnLivelinessChanged ON_LIVELINESS_CHANGED;
  /**
   * Called when samples are lost (gap in sequence numbers).
   */
  HddsOnSampleLost ON_SAMPLE_LOST;
  /**
   * Called when samples are rejected due to resource limits.
   */
  HddsOnSampleRejected ON_SAMPLE_REJECTED;
  /**
   * Called when the requested deadline is missed.
   */
  HddsOnDeadlineMissed ON_DEADLINE_MISSED;
  /**
   * Called when QoS is incompatible with a matched writer.
   */
  HddsOnIncompatibleQos ON_INCOMPATIBLE_QOS;
  /**
   * User-provided context pointer, passed to all callbacks.
   */
  void *USER_DATA;
} HddsReaderListener;

/**
 * Callback for sample written events (writer confirmation).
 *
 * # Parameters
 * - `data`: Pointer to serialized sample bytes
 * - `len`: Length of the serialized data in bytes
 * - `sequence_number`: Assigned RTPS sequence number
 * - `user_data`: User-provided context pointer
 */
typedef void (*HddsOnSampleWritten)(const uint8_t *data,
                                    uintptr_t len,
                                    uint64_t sequence_number,
                                    void *user_data);

/**
 * Publication matched status (C-compatible mirror of Rust PublicationMatchedStatus).
 *
 * Reports the number of subscriptions matched with this writer.
 */
typedef struct HddsPublicationMatchedStatus {
  /**
   * Total cumulative count of matched subscriptions.
   */
  uint32_t TOTAL_COUNT;
  /**
   * Change in total_count since last callback.
   */
  int32_t TOTAL_COUNT_CHANGE;
  /**
   * Current number of matched subscriptions.
   */
  uint32_t CURRENT_COUNT;
  /**
   * Change in current_count since last callback.
   */
  int32_t CURRENT_COUNT_CHANGE;
} HddsPublicationMatchedStatus;

/**
 * Callback for publication matched events.
 */
typedef void (*HddsOnPublicationMatched)(const struct HddsPublicationMatchedStatus *status,
                                         void *user_data);

/**
 * Callback for offered deadline missed events (writer side).
 *
 * # Parameters
 * - `instance_handle`: Handle of the instance that missed the deadline (0 if none)
 * - `user_data`: User-provided context pointer
 */
typedef void (*HddsOnOfferedDeadlineMissed)(uint64_t instance_handle, void *user_data);

/**
 * Callback for offered incompatible QoS events (writer side).
 *
 * # Parameters
 * - `policy_id`: ID of the incompatible QoS policy
 * - `policy_name`: Null-terminated policy name string (e.g., "RELIABILITY")
 * - `user_data`: User-provided context pointer
 */
typedef void (*HddsOnOfferedIncompatibleQos)(uint32_t policy_id,
                                             const char *policy_name,
                                             void *user_data);

/**
 * Callback for liveliness lost events (writer side).
 */
typedef void (*HddsOnLivelinessLost)(void *user_data);

/**
 * C-compatible DataWriter listener.
 *
 * Set callback fields to receive events. Any callback set to `None` (NULL)
 * will be silently ignored. The `user_data` pointer is passed through to
 * every callback invocation.
 *
 * # Example (C)
 *
 * ```c
 * HddsWriterListener listener = {0};
 * listener.on_publication_matched = my_match_callback;
 * listener.user_data = my_context;
 * hdds_writer_set_listener(writer, &listener);
 * ```
 */
typedef struct HddsWriterListener {
  /**
   * Called after a sample is successfully written.
   */
  HddsOnSampleWritten ON_SAMPLE_WRITTEN;
  /**
   * Called when the writer matches/unmatches with a reader.
   */
  HddsOnPublicationMatched ON_PUBLICATION_MATCHED;
  /**
   * Called when an offered deadline is missed.
   */
  HddsOnOfferedDeadlineMissed ON_OFFERED_DEADLINE_MISSED;
  /**
   * Called when QoS is incompatible with a matched reader.
   */
  HddsOnOfferedIncompatibleQos ON_OFFERED_INCOMPATIBLE_QOS;
  /**
   * Called when liveliness is lost (MANUAL_BY_* only).
   */
  HddsOnLivelinessLost ON_LIVELINESS_LOST;
  /**
   * User-provided context pointer, passed to all callbacks.
   */
  void *USER_DATA;
} HddsWriterListener;

/**
 * Opaque handle to a Publisher
 */
typedef struct HddsPublisher {
  uint8_t PRIVATE[0];
} HddsPublisher;

/**
 * Opaque handle to a Subscriber
 */
typedef struct HddsSubscriber {
  uint8_t PRIVATE[0];
} HddsSubscriber;

#if defined(HDDS_WITH_ROS2)
typedef struct RosString {
  char *DATA;
  uintptr_t SIZE;
  uintptr_t CAPACITY;
} RosString;
#endif

#if defined(HDDS_WITH_ROS2)
typedef struct RosStringSequence {
  struct RosString *DATA;
  uintptr_t SIZE;
  uintptr_t CAPACITY;
} RosStringSequence;
#endif

#if defined(HDDS_WITH_ROS2)
typedef struct RosOctetSequence {
  uint8_t *DATA;
  uintptr_t SIZE;
  uintptr_t CAPACITY;
} RosOctetSequence;
#endif

#if defined(HDDS_WITH_ROS2)
typedef struct RosBoolSequence {
  bool *DATA;
  uintptr_t SIZE;
  uintptr_t CAPACITY;
} RosBoolSequence;
#endif

#if defined(HDDS_WITH_ROS2)
typedef struct RosInt64Sequence {
  int64_t *DATA;
  uintptr_t SIZE;
  uintptr_t CAPACITY;
} RosInt64Sequence;
#endif

#if defined(HDDS_WITH_ROS2)
typedef struct RosDoubleSequence {
  double *DATA;
  uintptr_t SIZE;
  uintptr_t CAPACITY;
} RosDoubleSequence;
#endif

#if defined(HDDS_WITH_ROS2)
typedef struct ParameterValue {
  uint8_t TYPE;
  bool BOOL_VALUE;
  int64_t INTEGER_VALUE;
  double DOUBLE_VALUE;
  struct RosString STRING_VALUE;
  struct RosOctetSequence BYTE_ARRAY_VALUE;
  struct RosBoolSequence BOOL_ARRAY_VALUE;
  struct RosInt64Sequence INTEGER_ARRAY_VALUE;
  struct RosDoubleSequence DOUBLE_ARRAY_VALUE;
  struct RosStringSequence STRING_ARRAY_VALUE;
} ParameterValue;
#endif

#if defined(HDDS_WITH_ROS2)
typedef struct Parameter {
  struct RosString NAME;
  struct ParameterValue VALUE;
} Parameter;
#endif

#if defined(HDDS_WITH_ROS2)
typedef struct ParameterSequence {
  struct Parameter *DATA;
  uintptr_t SIZE;
  uintptr_t CAPACITY;
} ParameterSequence;
#endif

/**
 * Opaque handle to a security configuration.
 */
typedef struct HddsSecurityConfig {
  uint8_t PRIVATE[0];
} HddsSecurityConfig;

/**
 * Opaque handle to a MetricsCollector
 */
typedef struct HddsMetrics {
  uint8_t PRIVATE[0];
} HddsMetrics;

/**
 * Telemetry metrics snapshot (C-compatible)
 */
typedef struct HddsMetricsSnapshot {
  /**
   * Timestamp in nanoseconds since epoch
   */
  uint64_t TIMESTAMP_NS;
  /**
   * Total messages sent
   */
  uint64_t MESSAGES_SENT;
  /**
   * Total messages received
   */
  uint64_t MESSAGES_RECEIVED;
  /**
   * Total messages dropped
   */
  uint64_t MESSAGES_DROPPED;
  /**
   * Total bytes sent
   */
  uint64_t BYTES_SENT;
  /**
   * Latency p50 in nanoseconds
   */
  uint64_t LATENCY_P50_NS;
  /**
   * Latency p99 in nanoseconds
   */
  uint64_t LATENCY_P99_NS;
  /**
   * Latency p999 in nanoseconds
   */
  uint64_t LATENCY_P999_NS;
  /**
   * Merge full count (backpressure events)
   */
  uint64_t MERGE_FULL_COUNT;
  /**
   * Would-block count (send buffer full)
   */
  uint64_t WOULD_BLOCK_COUNT;
} HddsMetricsSnapshot;

/**
 * Opaque handle to a telemetry Exporter
 */
typedef struct HddsTelemetryExporter {
  uint8_t PRIVATE[0];
} HddsTelemetryExporter;

/**
 * Opaque handle to a participant configuration (builder).
 */
typedef struct HddsParticipantConfig {
  uint8_t PRIVATE[0];
} HddsParticipantConfig;

/**
 * Create a new DDS Participant with default settings (UdpMulticast transport)
 *
 * For network DDS communication, this is the recommended function.
 * Use `hdds_participant_create_with_transport` if you need intra-process mode.
 *
 * # Safety
 * - `name` must be a valid null-terminated C string.
 * - The returned handle must be released with `hdds_participant_destroy`.
 */
 struct HddsParticipant *hdds_participant_create(const char *aName);

/**
 * Create a new DDS Participant with specified transport mode
 *
 * # Safety
 * - `name` must be a valid null-terminated C string.
 * - The returned handle must be released with `hdds_participant_destroy`.
 *
 * # Arguments
 * * `name` - Participant name (null-terminated C string)
 * * `transport` - Transport mode:
 *   - `HddsTransportMode::HddsTransportIntraProcess` (0): No network, intra-process only
 *   - `HddsTransportMode::HddsTransportUdpMulticast` (1): UDP multicast for network discovery
 *
 * # Returns
 * Opaque participant handle, or NULL on failure
 */

struct HddsParticipant *hdds_participant_create_with_transport(const char *aName,
                                                               enum HddsTransportMode aTransport);

/**
 * Destroy a Participant
 *
 * # Safety
 * - `participant` must be a valid handle from `hdds_participant_create`, or NULL (no-op).
 * - Must not be called more than once with the same pointer.
 */
 void hdds_participant_destroy(struct HddsParticipant *aParticipant);

/**
 * Get the participant-level graph guard condition.
 *
 * # Safety
 * - `participant` must be a valid handle from `hdds_participant_create`.
 */

const struct HddsGuardCondition *hdds_participant_graph_guard_condition(struct HddsParticipant *aParticipant);

/**
 * Register a ROS 2 type support with the participant.
 *
 * # Safety
 * - `participant` must be a valid handle from `hdds_participant_create`.
 * - `type_support` must be a valid `rosidl_message_type_support_t` pointer.
 * - `out_handle` must be a valid pointer to write the result.
 */

enum HddsError hdds_participant_register_type_support(struct HddsParticipant *aParticipant,
                                                      uint32_t aDistro,
                                                      const rosidl_message_type_support_t *aTypeSupport,
                                                      const struct HddsTypeObject **aOutHandle);

/**
 * Release a type object handle.
 *
 * # Safety
 * - `handle` must be a valid handle from `hdds_participant_register_type_support`, or NULL.
 */
 void hdds_type_object_release(const struct HddsTypeObject *aHandle);

/**
 * Get the type hash from a type object handle.
 *
 * # Safety
 * - `handle` must be a valid handle from `hdds_participant_register_type_support`.
 * - `out_value` must point to a buffer of at least `value_len` bytes.
 */

enum HddsError hdds_type_object_hash(const struct HddsTypeObject *aHandle,
                                     uint8_t *aOutVersion,
                                     uint8_t *aOutValue,
                                     uintptr_t aValueLen);

/**
 * Get HDDS library version string
 *
 * # Safety
 * The returned pointer is valid for the lifetime of the process (static storage).
 */
 const char *hdds_version(void);

/**
 * Create a `DataWriter` for a topic
 *
 * # Safety
 * - `participant` must be a valid pointer returned from `hdds_participant_create`
 * - `topic_name` must be a valid null-terminated C string
 */

struct HddsDataWriter *hdds_writer_create(struct HddsParticipant *aParticipant,
                                          const char *aTopicName);

/**
 * Write data to a topic
 *
 * # Safety
 * - `writer` must be a valid pointer returned from `hdds_writer_create`
 * - `data` must point to valid memory of at least `len` bytes
 */

enum HddsError hdds_writer_write(struct HddsDataWriter *aWriter,
                                 const void *aData,
                                 uintptr_t aLen);

/**
 * Destroy a `DataWriter`
 *
 * # Safety
 * - `writer` must be a valid pointer returned from `hdds_writer_create`
 * - Must not be called more than once with the same pointer
 */
 void hdds_writer_destroy(struct HddsDataWriter *aWriter);

/**
 * Create a `DataWriter` for a topic with custom QoS
 *
 * # Safety
 * - `participant` must be a valid pointer returned from `hdds_participant_create`
 * - `topic_name` must be a valid null-terminated C string
 * - `qos` must be a valid pointer returned from `hdds_qos_*` functions (or NULL for default)
 */

struct HddsDataWriter *hdds_writer_create_with_qos(struct HddsParticipant *aParticipant,
                                                   const char *aTopicName,
                                                   const struct HddsQoS *aQos);

/**
 * Create a `DataWriter` for a topic with custom QoS and explicit type name.
 *
 * The `type_name` is announced via SEDP and must match the remote endpoint's
 * type name for topic matching (e.g. `"P_Mount_PSM::C_Rotational_Mount_setPosition"`).
 * If `type_name` is NULL, falls back to the default `"RawBytes"` type name.
 *
 * # Safety
 * - `participant` must be a valid pointer returned from `hdds_participant_create`
 * - `topic_name` must be a valid null-terminated C string
 * - `type_name` must be a valid null-terminated C string (or NULL for default)
 * - `qos` must be a valid pointer returned from `hdds_qos_*` functions (or NULL for default)
 */

struct HddsDataWriter *hdds_writer_create_with_type(struct HddsParticipant *aParticipant,
                                                    const char *aTopicName,
                                                    const char *aTypeName,
                                                    const struct HddsQoS *aQos);

/**
 * Create a `DataReader` for a topic
 *
 * # Safety
 * - `participant` must be a valid pointer returned from `hdds_participant_create`
 * - `topic_name` must be a valid null-terminated C string
 */

struct HddsDataReader *hdds_reader_create(struct HddsParticipant *aParticipant,
                                          const char *aTopicName);

/**
 * Create a `DataReader` for a topic with custom QoS
 *
 * # Safety
 * - `participant` must be a valid pointer returned from `hdds_participant_create`
 * - `topic_name` must be a valid null-terminated C string
 * - `qos` must be a valid pointer returned from `hdds_qos_*` functions (or NULL for default)
 */

struct HddsDataReader *hdds_reader_create_with_qos(struct HddsParticipant *aParticipant,
                                                   const char *aTopicName,
                                                   const struct HddsQoS *aQos);

/**
 * Create a `DataReader` for a topic with custom QoS and explicit type name.
 *
 * The `type_name` is announced via SEDP and must match the remote endpoint's
 * type name for topic matching (e.g. `"P_Mount_PSM::C_Rotational_Mount_setPosition"`).
 * If `type_name` is NULL, falls back to the default `"RawBytes"` type name.
 *
 * # Safety
 * - `participant` must be a valid pointer returned from `hdds_participant_create`
 * - `topic_name` must be a valid null-terminated C string
 * - `type_name` must be a valid null-terminated C string (or NULL for default)
 * - `qos` must be a valid pointer returned from `hdds_qos_*` functions (or NULL for default)
 */

struct HddsDataReader *hdds_reader_create_with_type(struct HddsParticipant *aParticipant,
                                                    const char *aTopicName,
                                                    const char *aTypeName,
                                                    const struct HddsQoS *aQos);

/**
 * Take data from a topic (non-blocking)
 *
 * # Safety
 * - `reader` must be a valid pointer returned from `hdds_reader_create`
 * - `data_out` must point to a valid buffer of at least `max_len` bytes
 * - `len_out` must be a valid pointer to write the actual data length
 */

enum HddsError hdds_reader_take(struct HddsDataReader *aReader,
                                void *aDataOut,
                                uintptr_t aMaxLen,
                                uintptr_t *aLenOut);

/**
 * Destroy a `DataReader`
 *
 * # Safety
 * - `reader` must be a valid pointer returned from `hdds_reader_create`
 * - Must not be called more than once with the same pointer
 */
 void hdds_reader_destroy(struct HddsDataReader *aReader);

/**
 * Get the status condition associated with a reader.
 *
 * # Safety
 * - `reader` must be a valid handle from `hdds_reader_create`.
 */
 const struct HddsStatusCondition *hdds_reader_get_status_condition(struct HddsDataReader *aReader);

/**
 * Release a previously acquired status condition.
 *
 * # Safety
 * - `condition` must be a valid handle from `hdds_reader_get_status_condition`.
 */
 void hdds_status_condition_release(const struct HddsStatusCondition *aCondition);

/**
 * Create a new guard condition.
 *
 * # Safety
 * The returned handle must be released with `hdds_guard_condition_release`.
 */
 const struct HddsGuardCondition *hdds_guard_condition_create(void);

/**
 * Release a guard condition.
 *
 * # Safety
 * - `condition` must be a valid handle from `hdds_guard_condition_create`.
 */
 void hdds_guard_condition_release(const struct HddsGuardCondition *aCondition);

/**
 * Set a guard condition's trigger value.
 *
 * # Safety
 * - `condition` must be a valid handle from `hdds_guard_condition_create`.
 */
 void hdds_guard_condition_set_trigger(const struct HddsGuardCondition *aCondition, bool aActive);

/**
 * Read a guard condition's current trigger value without modifying it.
 *
 * # Safety
 * - `condition` must be a valid handle from `hdds_guard_condition_create`.
 */
 bool hdds_guard_condition_get_trigger(const struct HddsGuardCondition *aCondition);

/**
 * Create a waitset.
 *
 * # Safety
 * The returned handle must be released with `hdds_waitset_destroy`.
 */
 struct HddsWaitSet *hdds_waitset_create(void);

/**
 * Destroy a waitset.
 *
 * # Safety
 * - `waitset` must be a valid handle from `hdds_waitset_create`, or NULL (no-op).
 */
 void hdds_waitset_destroy(struct HddsWaitSet *aWaitset);

/**
 * Attach a status condition to a waitset.
 *
 * # Safety
 * - `waitset` must be a valid handle from `hdds_waitset_create`.
 * - `condition` must be a valid handle from `hdds_reader_get_status_condition`.
 */

enum HddsError hdds_waitset_attach_status_condition(struct HddsWaitSet *aWaitset,
                                                    const struct HddsStatusCondition *aCondition);

/**
 * Attach a guard condition to a waitset.
 *
 * # Safety
 * - `waitset` must be a valid handle from `hdds_waitset_create`.
 * - `condition` must be a valid handle from `hdds_guard_condition_create`.
 */

enum HddsError hdds_waitset_attach_guard_condition(struct HddsWaitSet *aWaitset,
                                                   const struct HddsGuardCondition *aCondition);

/**
 * Detach a condition (status or guard) from a waitset.
 *
 * # Safety
 * - `waitset` must be a valid handle from `hdds_waitset_create`.
 * - `condition` must be a handle previously attached to this waitset.
 */
 enum HddsError hdds_waitset_detach_condition(struct HddsWaitSet *aWaitset, const void *aCondition);

/**
 * Wait for any attached condition to trigger.
 *
 * # Safety
 * - `waitset` must be a valid handle from `hdds_waitset_create`.
 * - `out_conditions` must point to an array of at least `max_conditions` pointers.
 * - `out_len` must be a valid pointer.
 */

enum HddsError hdds_waitset_wait(struct HddsWaitSet *aWaitset,
                                 int64_t aTimeoutNs,
                                 const void **aOutConditions,
                                 uintptr_t aMaxConditions,
                                 uintptr_t *aOutLen);

#if defined(HDDS_WITH_ROS2)
/**
 * Create a new rmw context.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */
 struct HddsRmwContext *hdds_rmw_context_create(const char *aName);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Destroy an rmw context.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */
 void hdds_rmw_context_destroy(struct HddsRmwContext *aCtx);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Get the graph guard key associated with the context.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */
 uint64_t hdds_rmw_context_graph_guard_key(struct HddsRmwContext *aCtx);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Copy the participant GUID prefix (12 bytes) into `out_prefix`.
 *
 * Returns the participant's stable GUID prefix, suitable for building
 * cross-process unique GIDs (rmw_gid_t).
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */
 enum HddsError hdds_rmw_context_guid_prefix(struct HddsRmwContext *aCtx, uint8_t *aOutPrefix);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Get the graph guard condition associated with the context.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

const struct HddsGuardCondition *hdds_rmw_context_graph_guard_condition(struct HddsRmwContext *aCtx);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Attach a guard condition to the rmw waitset.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_attach_guard_condition(struct HddsRmwContext *aCtx,
                                                       const struct HddsGuardCondition *aGuard,
                                                       uint64_t *aOutKey);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Attach a status condition to the rmw waitset.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_attach_status_condition(struct HddsRmwContext *aCtx,
                                                        const struct HddsStatusCondition *aStatus,
                                                        uint64_t *aOutKey);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Attach a reader to the rmw waitset (convenience helper).
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_attach_reader(struct HddsRmwContext *aCtx,
                                              struct HddsDataReader *aReader,
                                              uint64_t *aOutKey);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Create a DataReader bound to the rmw context participant.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_create_reader(struct HddsRmwContext *aCtx,
                                              const char *aTopicName,
                                              struct HddsDataReader **aOutReader);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Create a DataReader bound to the rmw context participant with custom QoS.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_create_reader_with_qos(struct HddsRmwContext *aCtx,
                                                       const char *aTopicName,
                                                       const struct HddsQoS *aQos,
                                                       struct HddsDataReader **aOutReader);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Destroy a DataReader created via the rmw context.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_destroy_reader(struct HddsRmwContext *aCtx,
                                               struct HddsDataReader *aReader);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_create_writer(struct HddsRmwContext *aCtx,
                                              const char *aTopicName,
                                              struct HddsDataWriter **aOutWriter);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_create_writer_with_qos(struct HddsRmwContext *aCtx,
                                                       const char *aTopicName,
                                                       const struct HddsQoS *aQos,
                                                       struct HddsDataWriter **aOutWriter);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_bind_topic_type(struct HddsRmwContext *aCtx,
                                                const char *aTopicName,
                                                const rosidl_message_type_support_t *aTypeSupport);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_destroy_writer(struct HddsRmwContext *aCtx,
                                               struct HddsDataWriter *aWriter);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_register_node(struct HddsRmwContext *aCtx,
                                              const char *aNodeName,
                                              const char *aNodeNamespace,
                                              const char *aNodeEnclave);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_unregister_node(struct HddsRmwContext *aCtx,
                                                const char *aNodeName,
                                                const char *aNodeNamespace);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_register_publisher_endpoint(struct HddsRmwContext *aCtx,
                                                            const char *aNodeName,
                                                            const char *aNodeNamespace,
                                                            const char *aTopicName,
                                                            const rosidl_message_type_support_t *aTypeSupport,
                                                            const uint8_t *aEndpointGid,
                                                            const struct HddsRmwQosProfile *aQosProfile);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_unregister_publisher_endpoint(struct HddsRmwContext *aCtx,
                                                              const char *aNodeName,
                                                              const char *aNodeNamespace,
                                                              const char *aTopicName,
                                                              const uint8_t *aEndpointGid);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_register_subscription_endpoint(struct HddsRmwContext *aCtx,
                                                               const char *aNodeName,
                                                               const char *aNodeNamespace,
                                                               const char *aTopicName,
                                                               const rosidl_message_type_support_t *aTypeSupport,
                                                               const uint8_t *aEndpointGid,
                                                               const struct HddsRmwQosProfile *aQosProfile);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_unregister_subscription_endpoint(struct HddsRmwContext *aCtx,
                                                                 const char *aNodeName,
                                                                 const char *aNodeNamespace,
                                                                 const char *aTopicName,
                                                                 const uint8_t *aEndpointGid);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_for_each_node(struct HddsRmwContext *aCtx,
                                              HddsNodeVisitor aVisitor,
                                              void *aUserData,
                                              uint64_t *aOutVersion,
                                              uintptr_t *aOutCount);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_for_each_node_with_enclave(struct HddsRmwContext *aCtx,
                                                           HddsNodeEnclaveVisitor aVisitor,
                                                           void *aUserData,
                                                           uint64_t *aOutVersion,
                                                           uintptr_t *aOutCount);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_for_each_publisher_endpoint(struct HddsRmwContext *aCtx,
                                                            const char *aNodeName,
                                                            const char *aNodeNamespace,
                                                            HddsEndpointVisitor aVisitor,
                                                            void *aUserData,
                                                            uint64_t *aOutVersion,
                                                            uintptr_t *aOutCount);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_for_each_subscription_endpoint(struct HddsRmwContext *aCtx,
                                                               const char *aNodeName,
                                                               const char *aNodeNamespace,
                                                               HddsEndpointVisitor aVisitor,
                                                               void *aUserData,
                                                               uint64_t *aOutVersion,
                                                               uintptr_t *aOutCount);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_for_each_topic(struct HddsRmwContext *aCtx,
                                               struct Option_HddsTopicVisitor aVisitor,
                                               void *aUserData,
                                               uint64_t *aOutVersion);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_for_each_user_locator(struct HddsRmwContext *aCtx,
                                                      struct Option_HddsLocatorVisitor aVisitor,
                                                      void *aUserData,
                                                      uintptr_t *aOutCount);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_publish(struct HddsRmwContext *aCtx,
                                        struct HddsDataWriter *aWriter,
                                        const rosidl_message_type_support_t *aTypeSupport,
                                        const void *aRosMessage);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_publish_with_codec(struct HddsRmwContext *aCtx,
                                                   struct HddsDataWriter *aWriter,
                                                   uint8_t aCodecKind,
                                                   const void *aRosMessage);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Try to read from SHM ring buffer for a topic (inter-process fast path).
 *
 * Returns OK with `*len_out > 0` if data was read from SHM.
 * Returns NOT_FOUND if no SHM data available (caller should fall back to RTPS).
 *
 * # Safety
 * - `ctx` must be a valid `HddsRmwContext`
 * - `topic` must be a valid C string
 * - `data_out` must point to a buffer of at least `max_len` bytes
 * - `len_out` must be a valid pointer
 */

enum HddsError hdds_rmw_context_shm_try_take(struct HddsRmwContext *aCtx,
                                             const char *aTopic,
                                             void *aDataOut,
                                             uintptr_t aMaxLen,
                                             uintptr_t *aLenOut);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Check if SHM data is available for a topic (non-blocking).
 *
 * Returns `true` (1) if data is available, `false` (0) otherwise.
 *
 * # Safety
 * - `ctx` must be a valid `HddsRmwContext`
 * - `topic` must be a valid C string
 */
 bool hdds_rmw_context_shm_has_data(struct HddsRmwContext *aCtx, const char *aTopic);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_deserialize_with_codec(uint8_t aCodecKind,
                                               const uint8_t *aData,
                                               uintptr_t aDataLen,
                                               void *aRosMessage);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Check if a ROS2 type has a dynamic TypeDescriptor available.
 * Returns true if the type is supported for dynamic deserialization.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */
 bool hdds_rmw_has_type_descriptor(const char *aTypeName);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Deserialize CDR data to a ROS2 message using dynamic types.
 * Returns Ok if successful, InvalidArgument if type not supported.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_deserialize_dynamic(const char *aTypeName,
                                            const uint8_t *aData,
                                            uintptr_t aDataLen,
                                            void *aRosMessage);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Detach a condition previously attached to the rmw waitset.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */
 enum HddsError hdds_rmw_context_detach_condition(struct HddsRmwContext *aCtx, uint64_t aKey);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Detach a reader previously attached to the rmw waitset.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_detach_reader(struct HddsRmwContext *aCtx,
                                              struct HddsDataReader *aReader);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Wait for the rmw context waitset.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_wait(struct HddsRmwContext *aCtx,
                                     int64_t aTimeoutNs,
                                     uint64_t *aOutKeys,
                                     const void **aOutConditions,
                                     uintptr_t aMaxConditions,
                                     uintptr_t *aOutLen);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Wait for reader notifications and report guard hits.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_context_wait_readers(struct HddsRmwContext *aCtx,
                                             int64_t aTimeoutNs,
                                             struct HddsDataReader **aOutReaders,
                                             uintptr_t aMaxReaders,
                                             uintptr_t *aOutLen,
                                             bool *aOutGuardTriggered);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Create an rmw waitset bound to a context.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */
 struct HddsRmwWaitSet *hdds_rmw_waitset_create(struct HddsRmwContext *aCtx);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Destroy an rmw waitset.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */
 void hdds_rmw_waitset_destroy(struct HddsRmwWaitSet *aWaitset);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Attach a reader to an rmw waitset.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_waitset_attach_reader(struct HddsRmwWaitSet *aWaitset,
                                              struct HddsDataReader *aReader);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Detach a reader from an rmw waitset.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_waitset_detach_reader(struct HddsRmwWaitSet *aWaitset,
                                              struct HddsDataReader *aReader);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 * Wait on an rmw waitset and report triggered readers and guard state.
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_waitset_wait(struct HddsRmwWaitSet *aWaitset,
                                     int64_t aTimeoutNs,
                                     struct HddsDataReader **aOutReaders,
                                     uintptr_t aMaxReaders,
                                     uintptr_t *aOutLen,
                                     bool *aOutGuardTriggered);
#endif

/**
 * Get the participant name
 *
 * # Safety
 * - `participant` must be a valid pointer returned from `hdds_participant_create`
 * - Returns a pointer to an internal string, valid until participant is destroyed
 *
 * # Returns
 * Pointer to null-terminated participant name, or NULL on error
 */
 const char *hdds_participant_name(struct HddsParticipant *aParticipant);

/**
 * Get the participant domain ID
 *
 * # Safety
 * - `participant` must be a valid pointer returned from `hdds_participant_create`
 *
 * # Returns
 * Domain ID (default 0), or 0xFFFFFFFF on error
 */
 uint32_t hdds_participant_domain_id(struct HddsParticipant *aParticipant);

/**
 * Get the participant ID (unique within domain)
 *
 * # Safety
 * - `participant` must be a valid pointer
 *
 * # Returns
 * Participant ID, or 0xFF on error
 */
 uint8_t hdds_participant_id(struct HddsParticipant *aParticipant);

/**
 * Get the topic name for a writer
 *
 * # Safety
 * - `writer` must be a valid pointer
 * - `buf` must point to a buffer of at least `buf_len` bytes
 * - `out_len` must be a valid pointer
 *
 * # Returns
 * `HddsError::HddsOk` on success, writes topic name to buffer
 */

enum HddsError hdds_writer_topic_name(struct HddsDataWriter *aWriter,
                                      char *aBuf,
                                      uintptr_t aBufLen,
                                      uintptr_t *aOutLen);

/**
 * Get the topic name for a reader
 *
 * # Safety
 * - `reader` must be a valid pointer
 * - `buf` must point to a buffer of at least `buf_len` bytes
 * - `out_len` must be a valid pointer
 *
 * # Returns
 * `HddsError::HddsOk` on success, writes topic name to buffer
 */

enum HddsError hdds_reader_topic_name(struct HddsDataReader *aReader,
                                      char *aBuf,
                                      uintptr_t aBufLen,
                                      uintptr_t *aOutLen);

/**
 * Install a listener on a DataReader.
 *
 * The listener struct is copied internally. The caller must ensure that
 * any `user_data` pointer and callback functions remain valid until the
 * listener is cleared or the reader is destroyed.
 *
 * # Safety
 *
 * - `reader` must be a valid pointer returned from `hdds_reader_create` or similar.
 * - `listener` must be a valid pointer to a properly initialized `HddsReaderListener`.
 *
 * # Returns
 *
 * `HddsOk` on success, `HddsInvalidArgument` if either pointer is null.
 */

enum HddsError hdds_reader_set_listener(struct HddsDataReader *aReader,
                                        const struct HddsReaderListener *aListener);

/**
 * Remove the listener from a DataReader.
 *
 * After this call, no more callbacks will be invoked for this reader.
 *
 * # Safety
 *
 * - `reader` must be a valid pointer returned from `hdds_reader_create` or similar.
 *
 * # Returns
 *
 * `HddsOk` on success, `HddsInvalidArgument` if the pointer is null.
 */
 enum HddsError hdds_reader_clear_listener(struct HddsDataReader *aReader);

/**
 * Install a listener on a DataWriter.
 *
 * The listener struct is copied internally. The caller must ensure that
 * any `user_data` pointer and callback functions remain valid until the
 * listener is cleared or the writer is destroyed.
 *
 * # Safety
 *
 * - `writer` must be a valid pointer returned from `hdds_writer_create` or similar.
 * - `listener` must be a valid pointer to a properly initialized `HddsWriterListener`.
 *
 * # Returns
 *
 * `HddsOk` on success, `HddsInvalidArgument` if either pointer is null.
 */

enum HddsError hdds_writer_set_listener(struct HddsDataWriter *aWriter,
                                        const struct HddsWriterListener *aListener);

/**
 * Remove the listener from a DataWriter.
 *
 * After this call, no more callbacks will be invoked for this writer.
 *
 * # Safety
 *
 * - `writer` must be a valid pointer returned from `hdds_writer_create` or similar.
 *
 * # Returns
 *
 * `HddsOk` on success, `HddsInvalidArgument` if the pointer is null.
 */
 enum HddsError hdds_writer_clear_listener(struct HddsDataWriter *aWriter);

/**
 * Initialize HDDS logging with console output
 *
 * # Safety
 * Must be called from a single thread during initialization.
 *
 * # Arguments
 * * `level` - Minimum log level to display
 *
 * # Returns
 * `HddsError::HddsOk` on success, `HddsError::HddsOperationFailed` if already initialized
 *
 * # Example (C)
 * ```c
 * hdds_logging_init(HDDS_LOG_INFO);
 * ```
 */
 enum HddsError hdds_logging_init(enum HddsLogLevel aLevel);

/**
 * Initialize HDDS logging with environment variable override
 *
 * Reads `RUST_LOG` environment variable if set, otherwise uses provided level.
 *
 * # Safety
 * Must be called from a single thread during initialization.
 *
 * # Arguments
 * * `default_level` - Default log level if `RUST_LOG` is not set
 *
 * # Returns
 * `HddsError::HddsOk` on success
 */
 enum HddsError hdds_logging_init_env(enum HddsLogLevel aDefaultLevel);

/**
 * Initialize HDDS logging with custom filter string
 *
 * # Safety
 * - `filter` must be a valid null-terminated C string or NULL.
 *
 * # Arguments
 * * `filter` - Log filter string (e.g., "hdds=debug,info")
 *
 * # Returns
 * `HddsError::HddsOk` on success
 *
 * # Example (C)
 * ```c
 * hdds_logging_init_with_filter("hdds=debug");
 * ```
 */
 enum HddsError hdds_logging_init_with_filter(const char *aFilter);

/**
 * Create a Publisher with default QoS
 *
 * # Safety
 * - `participant` must be a valid pointer
 *
 * # Returns
 * Publisher handle, or NULL on error
 */
 struct HddsPublisher *hdds_publisher_create(struct HddsParticipant *aParticipant);

/**
 * Create a Publisher with custom QoS
 *
 * # Safety
 * - `participant` must be a valid pointer
 * - `qos` can be NULL for default QoS
 *
 * # Returns
 * Publisher handle, or NULL on error
 */

struct HddsPublisher *hdds_publisher_create_with_qos(struct HddsParticipant *aParticipant,
                                                     const struct HddsQoS *aQos);

/**
 * Destroy a Publisher
 *
 * # Safety
 * - `publisher` must be a valid pointer or NULL
 */
 void hdds_publisher_destroy(struct HddsPublisher *aPublisher);

/**
 * Create a Subscriber with default QoS
 *
 * # Safety
 * - `participant` must be a valid pointer
 *
 * # Returns
 * Subscriber handle, or NULL on error
 */
 struct HddsSubscriber *hdds_subscriber_create(struct HddsParticipant *aParticipant);

/**
 * Create a Subscriber with custom QoS
 *
 * # Safety
 * - `participant` must be a valid pointer
 * - `qos` can be NULL for default QoS
 *
 * # Returns
 * Subscriber handle, or NULL on error
 */

struct HddsSubscriber *hdds_subscriber_create_with_qos(struct HddsParticipant *aParticipant,
                                                       const struct HddsQoS *aQos);

/**
 * Destroy a Subscriber
 *
 * # Safety
 * - `subscriber` must be a valid pointer or NULL
 */
 void hdds_subscriber_destroy(struct HddsSubscriber *aSubscriber);

/**
 * Create a DataWriter from a Publisher with default QoS
 *
 * # Safety
 * - `publisher` must be a valid pointer returned from `hdds_publisher_create`
 * - `topic_name` must be a valid null-terminated C string
 *
 * # Returns
 * DataWriter handle, or NULL on error
 */

struct HddsDataWriter *hdds_publisher_create_writer(struct HddsPublisher *aPublisher,
                                                    const char *aTopicName);

/**
 * Create a DataWriter from a Publisher with custom QoS
 *
 * # Safety
 * - `publisher` must be a valid pointer returned from `hdds_publisher_create`
 * - `topic_name` must be a valid null-terminated C string
 * - `qos` can be NULL for default QoS
 *
 * # Returns
 * DataWriter handle, or NULL on error
 */

struct HddsDataWriter *hdds_publisher_create_writer_with_qos(struct HddsPublisher *aPublisher,
                                                             const char *aTopicName,
                                                             const struct HddsQoS *aQos);

/**
 * Create a DataReader from a Subscriber with default QoS
 *
 * # Safety
 * - `subscriber` must be a valid pointer returned from `hdds_subscriber_create`
 * - `topic_name` must be a valid null-terminated C string
 *
 * # Returns
 * DataReader handle, or NULL on error
 */

struct HddsDataReader *hdds_subscriber_create_reader(struct HddsSubscriber *aSubscriber,
                                                     const char *aTopicName);

/**
 * Create a DataReader from a Subscriber with custom QoS
 *
 * # Safety
 * - `subscriber` must be a valid pointer returned from `hdds_subscriber_create`
 * - `topic_name` must be a valid null-terminated C string
 * - `qos` can be NULL for default QoS
 *
 * # Returns
 * DataReader handle, or NULL on error
 */

struct HddsDataReader *hdds_subscriber_create_reader_with_qos(struct HddsSubscriber *aSubscriber,
                                                              const char *aTopicName,
                                                              const struct HddsQoS *aQos);

/**
 * Create a default QoS profile (best-effort, volatile).
 *
 * # Safety
 * The returned pointer must be freed with `hdds_qos_destroy`.
 */
 struct HddsQoS *hdds_qos_default(void);

/**
 * Create a best-effort QoS profile.
 *
 * Best-effort QoS does not guarantee delivery but has lower overhead.
 *
 * # Safety
 * The returned pointer must be freed with `hdds_qos_destroy`.
 */
 struct HddsQoS *hdds_qos_best_effort(void);

/**
 * Create a reliable QoS profile.
 *
 * Reliable QoS guarantees delivery with NACK-driven retransmission.
 *
 * # Safety
 * The returned pointer must be freed with `hdds_qos_destroy`.
 */
 struct HddsQoS *hdds_qos_reliable(void);

/**
 * Create an RTI Connext-compatible QoS profile.
 *
 * Uses RTI Connext DDS 6.x defaults for interoperability.
 *
 * # Safety
 * The returned pointer must be freed with `hdds_qos_destroy`.
 */
 struct HddsQoS *hdds_qos_rti_defaults(void);

/**
 * Destroy a QoS profile.
 *
 * # Safety
 * - `qos` must be a valid pointer returned from a `hdds_qos_*` creation function.
 * - Must not be called more than once with the same pointer.
 */
 void hdds_qos_destroy(struct HddsQoS *aQos);

/**
 * Load QoS from a FastDDS XML profile file.
 *
 * Parses the XML file and extracts the default profile's QoS settings.
 * Supports all 22 DDS QoS policies.
 *
 * # Arguments
 * - `path`: Path to the FastDDS XML profile file (null-terminated C string).
 *
 * # Returns
 * - Valid pointer on success.
 * - NULL if the file cannot be read or parsed.
 *
 * # Safety
 * - `path` must be a valid null-terminated C string.
 * - The returned pointer must be freed with `hdds_qos_destroy`.
 */
 struct HddsQoS *hdds_qos_load_fastdds_xml(const char *aPath);

/**
 * Load QoS from a vendor XML file (auto-detect vendor).
 *
 * Automatically detects the vendor format and parses accordingly.
 * Currently supports: FastDDS (eProsima).
 *
 * # Arguments
 * - `path`: Path to the XML profile file (null-terminated C string).
 *
 * # Returns
 * - Valid pointer on success.
 * - NULL if the file cannot be read or parsed.
 *
 * # Safety
 * - `path` must be a valid null-terminated C string.
 * - The returned pointer must be freed with `hdds_qos_destroy`.
 */
 struct HddsQoS *hdds_qos_from_xml(const char *aPath);

/**
 * Set history depth (KEEP_LAST) on a QoS profile.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsError hdds_qos_set_history_depth(struct HddsQoS *aQos, uint32_t aDepth);

/**
 * Set history policy to KEEP_ALL.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsError hdds_qos_set_history_keep_all(struct HddsQoS *aQos);

/**
 * Set durability to VOLATILE.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsError hdds_qos_set_volatile(struct HddsQoS *aQos);

/**
 * Set durability to TRANSIENT_LOCAL.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsError hdds_qos_set_transient_local(struct HddsQoS *aQos);

/**
 * Set durability to PERSISTENT.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsError hdds_qos_set_persistent(struct HddsQoS *aQos);

/**
 * Set reliability to RELIABLE.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsError hdds_qos_set_reliable(struct HddsQoS *aQos);

/**
 * Set reliability to BEST_EFFORT.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsError hdds_qos_set_best_effort(struct HddsQoS *aQos);

/**
 * Set deadline period in nanoseconds.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsError hdds_qos_set_deadline_ns(struct HddsQoS *aQos, uint64_t aPeriodNs);

/**
 * Set lifespan duration in nanoseconds.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsError hdds_qos_set_lifespan_ns(struct HddsQoS *aQos, uint64_t aDurationNs);

/**
 * Set ownership to SHARED.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsError hdds_qos_set_ownership_shared(struct HddsQoS *aQos);

/**
 * Set ownership to EXCLUSIVE with given strength.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsError hdds_qos_set_ownership_exclusive(struct HddsQoS *aQos, int32_t aStrength);

/**
 * Add a partition name to the QoS.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 * - `partition` must be a valid null-terminated C string.
 */
 enum HddsError hdds_qos_add_partition(struct HddsQoS *aQos, const char *aPartition);

/**
 * Check if QoS is reliable.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 bool hdds_qos_is_reliable(const struct HddsQoS *aQos);

/**
 * Check if QoS is transient-local.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 bool hdds_qos_is_transient_local(const struct HddsQoS *aQos);

/**
 * Get history depth.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 uint32_t hdds_qos_get_history_depth(const struct HddsQoS *aQos);

/**
 * Get deadline period in nanoseconds.
 *
 * Returns `u64::MAX` if infinite.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 uint64_t hdds_qos_get_deadline_ns(const struct HddsQoS *aQos);

/**
 * Get lifespan duration in nanoseconds.
 *
 * Returns `u64::MAX` if infinite.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 uint64_t hdds_qos_get_lifespan_ns(const struct HddsQoS *aQos);

/**
 * Check if ownership is exclusive.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 bool hdds_qos_is_ownership_exclusive(const struct HddsQoS *aQos);

/**
 * Get ownership strength value.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 int32_t hdds_qos_get_ownership_strength(const struct HddsQoS *aQos);

/**
 * Get liveliness kind.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsLivelinessKind hdds_qos_get_liveliness_kind(const struct HddsQoS *aQos);

/**
 * Get liveliness lease duration in nanoseconds.
 *
 * Returns `u64::MAX` if infinite.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 uint64_t hdds_qos_get_liveliness_lease_ns(const struct HddsQoS *aQos);

/**
 * Get time-based filter minimum separation in nanoseconds.
 *
 * Returns 0 if no filtering (all samples delivered).
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 uint64_t hdds_qos_get_time_based_filter_ns(const struct HddsQoS *aQos);

/**
 * Get latency budget in nanoseconds.
 *
 * Returns 0 if no latency budget (best effort delivery).
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 uint64_t hdds_qos_get_latency_budget_ns(const struct HddsQoS *aQos);

/**
 * Get transport priority.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 int32_t hdds_qos_get_transport_priority(const struct HddsQoS *aQos);

/**
 * Get max samples resource limit.
 *
 * Returns `usize::MAX` for unlimited.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 uintptr_t hdds_qos_get_max_samples(const struct HddsQoS *aQos);

/**
 * Get max instances resource limit.
 *
 * Returns `usize::MAX` for unlimited.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 uintptr_t hdds_qos_get_max_instances(const struct HddsQoS *aQos);

/**
 * Get max samples per instance resource limit.
 *
 * Returns `usize::MAX` for unlimited.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 uintptr_t hdds_qos_get_max_samples_per_instance(const struct HddsQoS *aQos);

/**
 * Set liveliness to automatic with given lease duration in nanoseconds.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsError hdds_qos_set_liveliness_automatic_ns(struct HddsQoS *aQos, uint64_t aLeaseNs);

/**
 * Set liveliness to manual-by-participant with given lease duration in nanoseconds.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */

enum HddsError hdds_qos_set_liveliness_manual_participant_ns(struct HddsQoS *aQos,
                                                             uint64_t aLeaseNs);

/**
 * Set liveliness to manual-by-topic with given lease duration in nanoseconds.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsError hdds_qos_set_liveliness_manual_topic_ns(struct HddsQoS *aQos, uint64_t aLeaseNs);

/**
 * Set time-based filter minimum separation in nanoseconds.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsError hdds_qos_set_time_based_filter_ns(struct HddsQoS *aQos, uint64_t aMinSeparationNs);

/**
 * Set latency budget in nanoseconds.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsError hdds_qos_set_latency_budget_ns(struct HddsQoS *aQos, uint64_t aBudgetNs);

/**
 * Set transport priority.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */
 enum HddsError hdds_qos_set_transport_priority(struct HddsQoS *aQos, int32_t aPriority);

/**
 * Set resource limits.
 *
 * Use `usize::MAX` for any value to indicate unlimited.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 */

enum HddsError hdds_qos_set_resource_limits(struct HddsQoS *aQos,
                                            uintptr_t aMaxSamples,
                                            uintptr_t aMaxInstances,
                                            uintptr_t aMaxSamplesPerInstance);

/**
 * Clone a QoS profile.
 *
 * # Safety
 * - `qos` must be a valid pointer from `hdds_qos_*` functions.
 * - The returned pointer must be freed with `hdds_qos_destroy`.
 */
 struct HddsQoS *hdds_qos_clone(const struct HddsQoS *aQos);

#if defined(HDDS_WITH_ROS2)
extern bool rosidl_runtime_c__String__init(rosidl_runtime_c__String *aStr);
#endif

#if defined(HDDS_WITH_ROS2)
extern void rosidl_runtime_c__String__fini(rosidl_runtime_c__String *aStr);
#endif

#if defined(HDDS_WITH_ROS2)
extern bool rosidl_runtime_c__String__assign(rosidl_runtime_c__String *aStr, const char *aValue);
#endif

#if defined(HDDS_WITH_ROS2)
extern bool rosidl_runtime_c__U16String__init(rosidl_runtime_c__U16String *aStr);
#endif

#if defined(HDDS_WITH_ROS2)
extern void rosidl_runtime_c__U16String__fini(rosidl_runtime_c__U16String *aStr);
#endif

#if defined(HDDS_WITH_ROS2)
extern bool rosidl_runtime_c__U16String__assignn(rosidl_runtime_c__U16String *aStr,
                                                 const uint16_t *aValue,
                                                 uintptr_t aLen);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_deserialize_ros_message(const rosidl_message_type_support_t *aTypeSupport,
                                                const uint8_t *aData,
                                                uintptr_t aLen,
                                                void *aRosMessage);
#endif

#if defined(HDDS_WITH_ROS2)
/**
 *
 * # Safety
 * Caller must ensure all pointer arguments are valid or NULL.
 */

enum HddsError hdds_rmw_serialize_ros_message(const rosidl_message_type_support_t *aTypeSupport,
                                              const void *aRosMessage,
                                              uint8_t *aBuffer,
                                              uintptr_t aCapacity,
                                              uintptr_t *aOutLen);
#endif

#if defined(HDDS_WITH_ROS2)
extern bool rosidl_runtime_c__String__assignn(struct RosString *aStr,
                                              const char *aValue,
                                              uintptr_t aSize);
#endif

#if defined(HDDS_WITH_ROS2)
extern bool rosidl_runtime_c__String__Sequence__init(struct RosStringSequence *aSeq,
                                                     uintptr_t aSize);
#endif

#if defined(HDDS_WITH_ROS2)
extern void rosidl_runtime_c__String__Sequence__fini(struct RosStringSequence *aSeq);
#endif

#if defined(HDDS_WITH_ROS2)
extern bool rosidl_runtime_c__octet__Sequence__init(struct RosOctetSequence *aSeq, uintptr_t aSize);
#endif

#if defined(HDDS_WITH_ROS2)
extern void rosidl_runtime_c__octet__Sequence__fini(struct RosOctetSequence *aSeq);
#endif

#if defined(HDDS_WITH_ROS2)
extern bool rosidl_runtime_c__boolean__Sequence__init(struct RosBoolSequence *aSeq,
                                                      uintptr_t aSize);
#endif

#if defined(HDDS_WITH_ROS2)
extern void rosidl_runtime_c__boolean__Sequence__fini(struct RosBoolSequence *aSeq);
#endif

#if defined(HDDS_WITH_ROS2)
extern bool rosidl_runtime_c__int64__Sequence__init(struct RosInt64Sequence *aSeq, uintptr_t aSize);
#endif

#if defined(HDDS_WITH_ROS2)
extern void rosidl_runtime_c__int64__Sequence__fini(struct RosInt64Sequence *aSeq);
#endif

#if defined(HDDS_WITH_ROS2)
extern bool rosidl_runtime_c__double__Sequence__init(struct RosDoubleSequence *aSeq,
                                                     uintptr_t aSize);
#endif

#if defined(HDDS_WITH_ROS2)
extern void rosidl_runtime_c__double__Sequence__fini(struct RosDoubleSequence *aSeq);
#endif

#if defined(HDDS_WITH_ROS2)
extern bool rcl_interfaces__msg__Parameter__Sequence__init(struct ParameterSequence *aSeq,
                                                           uintptr_t aSize);
#endif

#if defined(HDDS_WITH_ROS2)
extern void rcl_interfaces__msg__Parameter__Sequence__fini(struct ParameterSequence *aSeq);
#endif

#if defined(HDDS_WITH_ROS2)
extern bool rosidl_runtime_c__String__assign(rosidl_runtime_c__String *aStr, const char *aValue);
#endif

#if defined(HDDS_WITH_ROS2)
extern bool rosidl_runtime_c__U16String__assignn(rosidl_runtime_c__U16String *aStr,
                                                 const uint16_t *aValue,
                                                 uintptr_t aLen);
#endif

/**
 * Create a new security configuration.
 *
 * Must be attached to a participant config via `hdds_config_set_security`
 * or freed with `hdds_security_config_destroy`.
 */
 struct HddsSecurityConfig *hdds_security_config_create(void);

/**
 * Destroy a security configuration.
 *
 * Only call this if NOT passed to `hdds_config_set_security` (which consumes it).
 *
 * # Safety
 * - `config` must be a valid pointer from `hdds_security_config_create`, or NULL.
 */
 void hdds_security_config_destroy(struct HddsSecurityConfig *aConfig);

/**
 * Set the identity certificate path (X.509 PEM format, required).
 *
 * # Safety
 * - `config` must be valid. `path` must be null-terminated.
 */

enum HddsError hdds_security_config_set_identity_cert(struct HddsSecurityConfig *aConfig,
                                                      const char *aPath);

/**
 * Set the private key path (PEM format, required).
 *
 * # Safety
 * - `config` must be valid. `path` must be null-terminated.
 */

enum HddsError hdds_security_config_set_private_key(struct HddsSecurityConfig *aConfig,
                                                    const char *aPath);

/**
 * Set the CA certificates path (PEM format, required).
 *
 * # Safety
 * - `config` must be valid. `path` must be null-terminated.
 */

enum HddsError hdds_security_config_set_ca_cert(struct HddsSecurityConfig *aConfig,
                                                const char *aPath);

/**
 * Set the governance XML path (optional, for domain-level security rules).
 *
 * # Safety
 * - `config` must be valid. `path` must be null-terminated.
 */

enum HddsError hdds_security_config_set_governance_xml(struct HddsSecurityConfig *aConfig,
                                                       const char *aPath);

/**
 * Set the permissions XML path (optional, for topic/partition authorization).
 *
 * # Safety
 * - `config` must be valid. `path` must be null-terminated.
 */

enum HddsError hdds_security_config_set_permissions_xml(struct HddsSecurityConfig *aConfig,
                                                        const char *aPath);

/**
 * Enable or disable AES-256-GCM encryption (default: false).
 *
 * # Safety
 * - `config` must be valid.
 */

enum HddsError hdds_security_config_enable_encryption(struct HddsSecurityConfig *aConfig,
                                                      bool aEnabled);

/**
 * Enable or disable audit logging (default: false).
 *
 * # Safety
 * - `config` must be valid.
 */

enum HddsError hdds_security_config_enable_audit_log(struct HddsSecurityConfig *aConfig,
                                                     bool aEnabled);

/**
 * Set audit log file path (optional, in-memory only if not set).
 *
 * # Safety
 * - `config` must be valid. `path` must be null-terminated.
 */

enum HddsError hdds_security_config_set_audit_log_path(struct HddsSecurityConfig *aConfig,
                                                       const char *aPath);

/**
 * Require authentication for all participants (default: true).
 *
 * # Safety
 * - `config` must be valid.
 */

enum HddsError hdds_security_config_require_authentication(struct HddsSecurityConfig *aConfig,
                                                           bool aRequired);

/**
 * Enable CRL/OCSP certificate revocation checking (default: false).
 *
 * Adds ~50-200ms network round-trip per participant.
 *
 * # Safety
 * - `config` must be valid.
 */

enum HddsError hdds_security_config_check_revocation(struct HddsSecurityConfig *aConfig,
                                                     bool aEnabled);

/**
 * Initialize the global metrics collector
 *
 * Creates a thread-safe metrics collector for the entire HDDS instance.
 * Safe to call multiple times - subsequent calls return the same instance.
 *
 * # Safety
 * The returned handle must be released with `hdds_telemetry_release`.
 *
 * # Returns
 * Handle to the metrics collector, or NULL on error
 */
 struct HddsMetrics *hdds_telemetry_init(void);

/**
 * Get the global metrics collector (if initialized)
 *
 * # Safety
 * The returned handle must be released with `hdds_telemetry_release`.
 *
 * # Returns
 * Handle to metrics collector, or NULL if not initialized
 */
 struct HddsMetrics *hdds_telemetry_get(void);

/**
 * Release a metrics handle
 *
 * # Safety
 * - `metrics` must be a valid pointer from `hdds_telemetry_init` or `hdds_telemetry_get`
 */
 void hdds_telemetry_release(struct HddsMetrics *aMetrics);

/**
 * Take a snapshot of current metrics
 *
 * # Safety
 * - `metrics` must be a valid handle
 * - `out` must be a valid pointer to `HddsMetricsSnapshot`
 *
 * # Returns
 * `HddsError::HddsOk` on success
 */

enum HddsError hdds_telemetry_snapshot(struct HddsMetrics *aMetrics,
                                       struct HddsMetricsSnapshot *aOut);

/**
 * Record a latency sample
 *
 * # Safety
 * - `metrics` must be a valid handle
 *
 * # Arguments
 * * `start_ns` - Start timestamp in nanoseconds
 * * `end_ns` - End timestamp in nanoseconds
 */

void hdds_telemetry_record_latency(struct HddsMetrics *aMetrics,
                                   uint64_t aStartNs,
                                   uint64_t aEndNs);

/**
 * Start the telemetry export server
 *
 * Creates a TCP server that streams metrics to connected clients (e.g., HDDS Viewer).
 *
 * # Safety
 * - `bind_addr` must be a valid null-terminated C string.
 * - The returned handle must be released with `hdds_telemetry_stop_exporter`.
 *
 * # Arguments
 * * `bind_addr` - IP address to bind (e.g., "127.0.0.1" or "0.0.0.0")
 * * `port` - Port number (default: 4242)
 *
 * # Returns
 * Handle to exporter, or NULL on error
 */
 struct HddsTelemetryExporter *hdds_telemetry_start_exporter(const char *aBindAddr, uint16_t aPort);

/**
 * Stop and release the telemetry exporter
 *
 * # Safety
 * - `exporter` must be a valid pointer from `hdds_telemetry_start_exporter`
 */
 void hdds_telemetry_stop_exporter(struct HddsTelemetryExporter *aExporter);

/**
 * Create a new participant configuration (builder).
 *
 * The returned handle must be passed to `hdds_config_build` (which consumes it)
 * or freed with `hdds_config_destroy` if not used.
 *
 * # Safety
 * - `name` must be a valid null-terminated C string.
 */
 struct HddsParticipantConfig *hdds_config_create(const char *aName);

/**
 * Destroy a participant configuration without building.
 *
 * Only call this if you do NOT call `hdds_config_build`.
 *
 * # Safety
 * - `config` must be a valid pointer from `hdds_config_create`, or NULL.
 */
 void hdds_config_destroy(struct HddsParticipantConfig *aConfig);

/**
 * Set the DDS domain ID.
 *
 * # Safety
 * - `config` must be a valid pointer from `hdds_config_create`.
 */

enum HddsError hdds_config_set_domain_id(struct HddsParticipantConfig *aConfig,
                                         uint32_t aDomainId);

/**
 * Set the participant ID (for port assignment).
 *
 * Each participant on the same host should have a unique ID (0-119).
 * If not set, ports are auto-probed.
 *
 * # Safety
 * - `config` must be a valid pointer from `hdds_config_create`.
 */

enum HddsError hdds_config_set_participant_id(struct HddsParticipantConfig *aConfig,
                                              uint8_t aParticipantId);

/**
 * Set the transport mode (IntraProcess or UdpMulticast).
 *
 * # Safety
 * - `config` must be a valid pointer from `hdds_config_create`.
 */

enum HddsError hdds_config_set_transport_mode(struct HddsParticipantConfig *aConfig,
                                              enum HddsTransportMode aMode);

/**
 * Set custom discovery ports (override RTPS default port formula).
 *
 * # Safety
 * - `config` must be a valid pointer from `hdds_config_create`.
 */

enum HddsError hdds_config_set_discovery_ports(struct HddsParticipantConfig *aConfig,
                                               uint16_t aSpdpMulticast,
                                               uint16_t aSedpUnicast,
                                               uint16_t aUserUnicast);

/**
 * Add a static UDP peer for unicast discovery (e.g. embedded devices).
 *
 * Can be called multiple times.
 *
 * # Safety
 * - `config` must be a valid pointer from `hdds_config_create`.
 * - `addr` must be a valid null-terminated C string in "host:port" format.
 */

enum HddsError hdds_config_add_static_peer(struct HddsParticipantConfig *aConfig,
                                           const char *aAddr);

/**
 * Set shared memory policy.
 *
 * # Safety
 * - `config` must be a valid pointer from `hdds_config_create`.
 */

enum HddsError hdds_config_set_shm_policy(struct HddsParticipantConfig *aConfig,
                                          enum HddsShmPolicy aPolicy);

/**
 * Enable TCP transport with a listen port.
 *
 * This enables hybrid mode (UDP discovery + TCP data) by default.
 *
 * # Safety
 * - `config` must be a valid pointer from `hdds_config_create`.
 */
 enum HddsError hdds_config_enable_tcp(struct HddsParticipantConfig *aConfig, uint16_t aListenPort);

/**
 * Set TCP role (Auto, ServerOnly, ClientOnly).
 *
 * # Safety
 * - `config` must be a valid pointer from `hdds_config_create`.
 */

enum HddsError hdds_config_set_tcp_role(struct HddsParticipantConfig *aConfig,
                                        enum HddsTcpRole aRole);

/**
 * Add a TCP initial peer address (for TCP-only or client mode).
 *
 * Can be called multiple times to add multiple peers.
 *
 * # Safety
 * - `config` must be a valid pointer from `hdds_config_create`.
 * - `addr` must be a valid null-terminated C string in "host:port" format.
 */
 enum HddsError hdds_config_add_tcp_peer(struct HddsParticipantConfig *aConfig, const char *aAddr);

/**
 * Set TCP nodelay option (disable Nagle's algorithm).
 *
 * # Safety
 * - `config` must be a valid pointer from `hdds_config_create`.
 */
 enum HddsError hdds_config_set_tcp_nodelay(struct HddsParticipantConfig *aConfig, bool aNodelay);

/**
 * Enable TLS on TCP transport.
 *
 * # Safety
 * - `config` must be a valid pointer from `hdds_config_create`.
 */
 enum HddsError hdds_config_enable_tls(struct HddsParticipantConfig *aConfig);

/**
 * Set transport preference (UDP-only, TCP-only, hybrid, SHM+TCP, etc.).
 *
 * # Safety
 * - `config` must be a valid pointer from `hdds_config_create`.
 */

enum HddsError hdds_config_set_transport_preference(struct HddsParticipantConfig *aConfig,
                                                    enum HddsTransportPreference aPref);

/**
 * Attach a security configuration to this participant config.
 *
 * **This consumes the security config handle.** Do NOT call
 * `hdds_security_config_destroy` after this.
 *
 * Requires the `security` feature to be enabled at compile time.
 *
 * # Safety
 * - `config` must be a valid pointer from `hdds_config_create`.
 * - `security` must be a valid pointer from `hdds_security_config_create`.
 */

enum HddsError hdds_config_set_security(struct HddsParticipantConfig *aConfig,
                                        struct HddsSecurityConfig *aSecurity);

/**
 * Build a Participant from the configuration.
 *
 * **This consumes the config handle.** Do NOT call `hdds_config_destroy`
 * after this. If build fails, the config is still consumed and NULL is returned.
 *
 * # Safety
 * - `config` must be a valid pointer from `hdds_config_create`.
 * - After this call, `config` is invalid (consumed).
 */
 struct HddsParticipant *hdds_config_build(struct HddsParticipantConfig *aConfig);

#endif  /* HDDS_H */
