#ifndef XHIM_XHIM_V1_H_
#define XHIM_XHIM_V1_H_

#include <stdint.h>

#if defined(_WIN32)
#define XHIM_V1_CALL __cdecl
#if defined(XHIM_V1_SHARED_EXPORTS)
#define XHIM_V1_API __declspec(dllexport)
#elif defined(XHIM_V1_SHARED_IMPORTS)
#define XHIM_V1_API __declspec(dllimport)
#else
#define XHIM_V1_API
#endif
#else
#define XHIM_V1_CALL
#if defined(XHIM_V1_SHARED_EXPORTS)
#define XHIM_V1_API __attribute__((visibility("default")))
#else
#define XHIM_V1_API
#endif
#endif

#ifdef __cplusplus
extern "C" {
#endif

#define XHIM_V1_ABI_VERSION ((uint32_t)0x00010000u)
#define XHIM_V1_DEFAULT_EVENT_QUEUE_CAPACITY ((uint32_t)1024u)
#define XHIM_V1_MAX_EVENT_QUEUE_CAPACITY ((uint32_t)65536u)
#define XHIM_V1_DEFAULT_MESSAGE_PAGE_SIZE ((uint32_t)50u)
#define XHIM_V1_MAX_MESSAGE_PAGE_SIZE ((uint32_t)200u)
#define XHIM_V1_MAX_MESSAGE_SEARCH_CONTENT_TYPES ((uint32_t)32u)
#define XHIM_V1_DEFAULT_CONVERSATION_PAGE_SIZE ((uint32_t)50u)
#define XHIM_V1_MAX_CONVERSATION_PAGE_SIZE ((uint32_t)200u)
#define XHIM_V1_DEFAULT_SOCIAL_PAGE_SIZE ((uint32_t)50u)
#define XHIM_V1_MAX_SOCIAL_PAGE_SIZE ((uint32_t)200u)
#define XHIM_V1_MAX_USER_PROFILE_BATCH_SIZE ((uint32_t)100u)
#define XHIM_V1_MAX_GROUP_MUTATION_MEMBERS ((uint32_t)500u)
#define XHIM_V1_MAX_DEVICE_SESSIONS ((uint32_t)100u)
#define XHIM_V1_MAX_MARK_ALL_CHANGED_READS ((uint32_t)100u)
#define XHIM_V1_MAX_CONVERSATION_PEER_READS ((uint32_t)1000u)
#define XHIM_V1_CLIENT_PROTOCOL_VERSION ((uint32_t)2u)
#define XHIM_V1_MAX_COMPATIBILITY_CAPABILITIES ((uint32_t)32u)
#define XHIM_V1_MAX_CAPABILITY_NAME_BYTES ((uint32_t)128u)
#define XHIM_V1_MAX_COMPATIBILITY_VERSION_BYTES ((uint32_t)128u)
#define XHIM_V1_MAX_DEVICE_SESSION_ID_BYTES ((uint32_t)512u)
#define XHIM_V1_MAX_FRIEND_REMARK_BYTES ((uint32_t)512u)
#define XHIM_V1_MEDIA_TASK_SNAPSHOT_SCHEMA_VERSION ((uint32_t)1u)
#define XHIM_V1_MEDIA_TASK_EVENT_SCHEMA_VERSION ((uint32_t)1u)
#define XHIM_V1_PROJECTION_EVENT_SCHEMA_VERSION ((uint32_t)1u)
#define XHIM_V1_DIAGNOSTICS_SNAPSHOT_SCHEMA_VERSION ((uint32_t)1u)
#define XHIM_V1_COMPATIBILITY_SNAPSHOT_SCHEMA_VERSION ((uint32_t)1u)
#define XHIM_V1_DEVICE_SESSION_POLICY_SCHEMA_VERSION ((uint32_t)1u)
#define XHIM_V1_CONVERSATION_PREFERENCE_FLAG_NOTIFICATIONS_MUTED              \
  ((uint64_t)0x0000000000000001ull)
#define XHIM_V1_PROFILE_UPDATE_DISPLAY_NAME ((uint32_t)0x00000001u)
#define XHIM_V1_PROFILE_UPDATE_AVATAR_URL ((uint32_t)0x00000002u)
#define XHIM_V1_PROFILE_UPDATE_BIO ((uint32_t)0x00000004u)

typedef struct xhim_v1_client xhim_v1_client_t;
typedef struct xhim_v1_subscription xhim_v1_subscription_t;
typedef struct xhim_v1_offline_reader xhim_v1_offline_reader_t;
typedef struct xhim_v1_media_cache_reader xhim_v1_media_cache_reader_t;

typedef struct xhim_v1_bytes_view {
  const uint8_t *data;
  uint64_t len;
} xhim_v1_bytes_view_t;

typedef struct xhim_v1_inline_utf8_128 {
  uint32_t byte_count;
  uint8_t bytes[XHIM_V1_MAX_COMPATIBILITY_VERSION_BYTES];
} xhim_v1_inline_utf8_128_t;

typedef struct xhim_v1_inline_utf8_512 {
  uint32_t byte_count;
  uint8_t bytes[XHIM_V1_MAX_DEVICE_SESSION_ID_BYTES];
} xhim_v1_inline_utf8_512_t;

typedef enum xhim_v1_status_code {
  XHIM_V1_STATUS_OK = 0,
  XHIM_V1_STATUS_INVALID_ARGUMENT = 1,
  XHIM_V1_STATUS_INVALID_STATE = 2,
  XHIM_V1_STATUS_NOT_INITIALIZED = 3,
  XHIM_V1_STATUS_ALREADY_CLOSED = 4,
  XHIM_V1_STATUS_BACKEND_NOT_CONFIGURED = 5,
  XHIM_V1_STATUS_STORAGE_ERROR = 100,
  XHIM_V1_STATUS_IDEMPOTENCY_CONFLICT = 101,
  XHIM_V1_STATUS_NOT_FOUND = 102,
  XHIM_V1_STATUS_UNSUPPORTED = 103,
  XHIM_V1_STATUS_FORBIDDEN = 104,
  XHIM_V1_STATUS_CANCELLED = 200,
  XHIM_V1_STATUS_SDK_SHUTDOWN = 201,
  XHIM_V1_STATUS_CALLBACK_QUEUE_FULL = 202,
  XHIM_V1_STATUS_CREDENTIAL_REQUIRED = 203,
  XHIM_V1_STATUS_INTERNAL_ERROR = 900
} xhim_v1_status_code_t;

typedef enum xhim_v1_push_platform {
  XHIM_V1_PUSH_PLATFORM_APNS = 1,
  XHIM_V1_PUSH_PLATFORM_FCM = 2,
  XHIM_V1_PUSH_PLATFORM_HUAWEI = 3,
  XHIM_V1_PUSH_PLATFORM_WEB = 4
} xhim_v1_push_platform_t;

typedef enum xhim_v1_client_platform {
  XHIM_V1_CLIENT_PLATFORM_IOS = 1,
  XHIM_V1_CLIENT_PLATFORM_ANDROID = 2,
  XHIM_V1_CLIENT_PLATFORM_MACOS = 3,
  XHIM_V1_CLIENT_PLATFORM_WINDOWS = 4,
  XHIM_V1_CLIENT_PLATFORM_HARMONYOS = 5,
  XHIM_V1_CLIENT_PLATFORM_WEB = 6,
  XHIM_V1_CLIENT_PLATFORM_LINUX = 7,
  XHIM_V1_CLIENT_PLATFORM_UNKNOWN = 8
} xhim_v1_client_platform_t;

typedef enum xhim_v1_user_action {
  XHIM_V1_USER_ACTION_NONE = 0,
  XHIM_V1_USER_ACTION_RETRY = 1,
  XHIM_V1_USER_ACTION_UPDATE_CREDENTIAL = 2,
  XHIM_V1_USER_ACTION_CHECK_NETWORK = 3,
  XHIM_V1_USER_ACTION_CONTACT_SUPPORT = 4
} xhim_v1_user_action_t;

typedef enum xhim_v1_client_state {
  XHIM_V1_CLIENT_STATE_CREATED = 0,
  XHIM_V1_CLIENT_STATE_STARTED = 1,
  XHIM_V1_CLIENT_STATE_AUTHENTICATING = 2,
  XHIM_V1_CLIENT_STATE_CONNECTING = 3,
  XHIM_V1_CLIENT_STATE_SYNCHRONIZING = 4,
  XHIM_V1_CLIENT_STATE_READY = 5,
  XHIM_V1_CLIENT_STATE_CREDENTIAL_REQUIRED = 6,
  XHIM_V1_CLIENT_STATE_LOGGING_OUT = 7,
  XHIM_V1_CLIENT_STATE_CLOSED = 8,
  XHIM_V1_CLIENT_STATE_FATAL = 9
} xhim_v1_client_state_t;

typedef enum xhim_v1_event_kind {
  XHIM_V1_EVENT_STATE_CHANGED = 1,
  XHIM_V1_EVENT_MESSAGE_QUEUED = 2,
  XHIM_V1_EVENT_MESSAGE_RETRY_QUEUED = 3,
  XHIM_V1_EVENT_MESSAGE_CANCELLED = 4,
  XHIM_V1_EVENT_CONVERSATION_READ_CHANGED = 5,
  XHIM_V1_EVENT_MESSAGE_MUTATED = 6,
  XHIM_V1_EVENT_MEDIA_TASK_UPDATED = 7,
  XHIM_V1_EVENT_MESSAGE_UPSERTED = 8,
  XHIM_V1_EVENT_MESSAGE_STATE_CHANGED = 9,
  XHIM_V1_EVENT_CONVERSATION_CHANGED = 10,
  XHIM_V1_EVENT_SOCIAL_CHANGED = 11,
  XHIM_V1_EVENT_SYNC_APPLIED = 12,
  XHIM_V1_EVENT_PRESENCE_CHANGED = 13,
  XHIM_V1_EVENT_TYPING_CHANGED = 14
} xhim_v1_event_kind_t;

typedef enum xhim_v1_projection_change_origin {
  XHIM_V1_PROJECTION_ORIGIN_LOCAL = 1,
  XHIM_V1_PROJECTION_ORIGIN_REMOTE_SYNC = 2,
  XHIM_V1_PROJECTION_ORIGIN_OUTBOX = 3,
  XHIM_V1_PROJECTION_ORIGIN_REALTIME = 4
} xhim_v1_projection_change_origin_t;

typedef enum xhim_v1_presence_status {
  XHIM_V1_PRESENCE_ONLINE = 1,
  XHIM_V1_PRESENCE_AWAY = 2,
  XHIM_V1_PRESENCE_OFFLINE = 3
} xhim_v1_presence_status_t;

typedef enum xhim_v1_message_state {
  XHIM_V1_MESSAGE_STATE_PENDING = 0,
  XHIM_V1_MESSAGE_STATE_SENDING = 1,
  XHIM_V1_MESSAGE_STATE_RETRYING = 2,
  XHIM_V1_MESSAGE_STATE_SERVER_ACCEPTED = 3,
  XHIM_V1_MESSAGE_STATE_FAILED = 4,
  XHIM_V1_MESSAGE_STATE_CANCELLED = 5
} xhim_v1_message_state_t;

typedef enum xhim_v1_message_mutation_kind {
  XHIM_V1_MESSAGE_MUTATION_NONE = 0,
  XHIM_V1_MESSAGE_MUTATION_EDIT_TEXT = 1,
  XHIM_V1_MESSAGE_MUTATION_RECALL = 2
} xhim_v1_message_mutation_kind_t;

typedef enum xhim_v1_message_content_kind {
  XHIM_V1_MESSAGE_CONTENT_TEXT = 1,
  XHIM_V1_MESSAGE_CONTENT_IMAGE = 2,
  XHIM_V1_MESSAGE_CONTENT_AUDIO = 3,
  XHIM_V1_MESSAGE_CONTENT_VIDEO = 4,
  XHIM_V1_MESSAGE_CONTENT_FILE = 5,
  XHIM_V1_MESSAGE_CONTENT_CUSTOM = 1000
} xhim_v1_message_content_kind_t;

/*
 * Media task values are stable, persisted workflow states. Consumers must
 * treat an unknown numeric value as a future state, preserve the task_id, and
 * query the task again instead of coercing it to FAILED.
 */
typedef enum xhim_v1_media_task_state {
  XHIM_V1_MEDIA_TASK_PENDING = 0,
  XHIM_V1_MEDIA_TASK_AUTHORIZING = 1,
  XHIM_V1_MEDIA_TASK_TRANSFERRING = 2,
  XHIM_V1_MEDIA_TASK_PAUSED = 3,
  XHIM_V1_MEDIA_TASK_VERIFYING = 4,
  XHIM_V1_MEDIA_TASK_COMPLETED = 5,
  XHIM_V1_MEDIA_TASK_FAILED = 6,
  XHIM_V1_MEDIA_TASK_CANCELLED = 7
} xhim_v1_media_task_state_t;

typedef enum xhim_v1_media_task_direction {
  XHIM_V1_MEDIA_TASK_UPLOAD = 0,
  XHIM_V1_MEDIA_TASK_DOWNLOAD = 1
} xhim_v1_media_task_direction_t;

typedef enum xhim_v1_social_projection_kind {
  XHIM_V1_SOCIAL_FRIEND_REQUESTS = 1,
  XHIM_V1_SOCIAL_FRIENDSHIPS = 2,
  XHIM_V1_SOCIAL_GROUPS = 3,
  XHIM_V1_SOCIAL_GROUP_MEMBERS = 4,
  XHIM_V1_SOCIAL_BLOCKS = 5,
  XHIM_V1_SOCIAL_GROUP_JOIN_REQUESTS = 6
} xhim_v1_social_projection_kind_t;

typedef enum xhim_v1_friend_request_state {
  XHIM_V1_FRIEND_REQUEST_PENDING = 1,
  XHIM_V1_FRIEND_REQUEST_ACCEPTED = 2,
  XHIM_V1_FRIEND_REQUEST_REJECTED = 3
} xhim_v1_friend_request_state_t;

typedef enum xhim_v1_group_member_role {
  XHIM_V1_GROUP_MEMBER_OWNER = 1,
  XHIM_V1_GROUP_MEMBER_ADMIN = 2,
  XHIM_V1_GROUP_MEMBER_MEMBER = 3
} xhim_v1_group_member_role_t;

typedef enum xhim_v1_group_member_state {
  XHIM_V1_GROUP_MEMBER_JOINED = 1,
  XHIM_V1_GROUP_MEMBER_REMOVED = 2
} xhim_v1_group_member_state_t;

typedef enum xhim_v1_group_join_request_state {
  XHIM_V1_GROUP_JOIN_REQUEST_PENDING = 1,
  XHIM_V1_GROUP_JOIN_REQUEST_ACCEPTED = 2,
  XHIM_V1_GROUP_JOIN_REQUEST_REJECTED = 3
} xhim_v1_group_join_request_state_t;

typedef enum xhim_v1_friend_request_decision {
  XHIM_V1_FRIEND_REQUEST_DECISION_ACCEPT = 1,
  XHIM_V1_FRIEND_REQUEST_DECISION_REJECT = 2
} xhim_v1_friend_request_decision_t;

typedef enum xhim_v1_group_join_decision {
  XHIM_V1_GROUP_JOIN_DECISION_ACCEPT = 1,
  XHIM_V1_GROUP_JOIN_DECISION_REJECT = 2
} xhim_v1_group_join_decision_t;

typedef enum xhim_v1_group_governance_action {
  XHIM_V1_GROUP_GOVERNANCE_SET_ADMIN = 1,
  XHIM_V1_GROUP_GOVERNANCE_SET_MUTE = 2,
  XHIM_V1_GROUP_GOVERNANCE_TRANSFER_OWNER = 3,
  XHIM_V1_GROUP_GOVERNANCE_SET_JOIN_POLICY = 4,
  XHIM_V1_GROUP_GOVERNANCE_SET_PROFILE = 5
} xhim_v1_group_governance_action_t;

#define XHIM_V1_CONTENT_TYPE_TEXT "text/plain"
#define XHIM_V1_CONTENT_TYPE_IMAGE "xhim.media.image"
#define XHIM_V1_CONTENT_TYPE_AUDIO "xhim.media.audio"
#define XHIM_V1_CONTENT_TYPE_VIDEO "xhim.media.video"
#define XHIM_V1_CONTENT_TYPE_FILE "xhim.media.file"

/*
 * Development-only deterministic adapters. They drive the real ClientEngine,
 * SQLite, empty high-watermark Sync, and local Outbox ACK path, but do not
 * authenticate against a service or perform network I/O. A distribution may
 * compile this flag out with XHIM_ENABLE_LOCAL_PREVIEW=OFF. Production
 * integrations must leave it unset and embed their product adapters.
 */
#define XHIM_V1_CLIENT_FLAG_LOCAL_PREVIEW ((uint32_t)0x00000001u)

typedef struct xhim_v1_error {
  uint32_t struct_size;
  uint32_t abi_version;
  int32_t code;
  int32_t native_code;
  uint8_t retryable;
  uint8_t reserved[7];
  xhim_v1_bytes_view_t message;
  /*
   * Added after the original v1 prefix. Every view is borrowed for the
   * callback duration. domain + stable_code are the machine-readable contract;
   * message is diagnostic text and must not drive product behavior.
   */
  xhim_v1_bytes_view_t domain;
  xhim_v1_bytes_view_t stable_code;
  xhim_v1_bytes_view_t operation_id;
  xhim_v1_bytes_view_t trace_id;
  int64_t retry_after_ms;
  int32_t user_action;
  uint32_t reserved_u32;
  uint64_t reserved_u64[2];
} xhim_v1_error_t;

typedef struct xhim_v1_event {
  uint32_t struct_size;
  uint32_t abi_version;
  int32_t kind;
  int32_t state;
  uint64_t account_epoch;
  uint64_t connection_generation;
  xhim_v1_bytes_view_t payload;
  /*
   * Additive v1 tail. MEDIA_TASK_UPDATED uses schema 1 and payload is the
   * UTF-8 task_id. Projection events use schema 1; payload is their primary
   * identifier for simple consumers, while the typed fields below carry the
   * complete lightweight scope. Existing event kinds use schema 0.
   */
  uint32_t payload_schema_version;
  uint32_t reserved_u32;
  /*
   * Projection-event tail. Byte views are borrowed for the callback duration.
   * No message payload, SQLite object, credential, endpoint, or file path is
   * exposed. projection_revision is a per-client invalidation sequence: gaps
   * mean "re-query", not that consumers should replay a journal.
   */
  uint64_t projection_revision;
  uint64_t entity_revision;
  int64_t sequence;
  uint64_t affected_count;
  int32_t projection_origin;
  int32_t social_projection_kind;
  int32_t projection_message_state;
  uint32_t projection_reserved_u32;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t client_message_id;
  xhim_v1_bytes_view_t server_message_id;
  xhim_v1_bytes_view_t scope_id;
  /*
   * Transient realtime tail. PRESENCE_CHANGED and TYPING_CHANGED use schema 1.
   * scope_id is the subject user, conversation_id scopes typing, and event_id
   * is the server event identity. State must be expired locally at
   * transient_expires_at_ms because stop/offline frames are best effort.
   */
  uint64_t transient_sequence;
  int64_t transient_expires_at_ms;
  int32_t transient_presence_status;
  uint32_t transient_is_typing;
  xhim_v1_bytes_view_t event_id;
} xhim_v1_event_t;

/*
 * Immutable local message snapshot. Byte views are borrowed and remain valid
 * only for the duration of xhim_v1_message_completion_callback.
 *
 * payload contains the exact immutable envelope bytes. content_type is the
 * stable built-in type or product namespace and content_version is scoped to
 * that type. Media payloads contain descriptors/MediaRef values, never the raw
 * media object or an expiring signed URL.
 */
typedef struct xhim_v1_message_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  int32_t state;
  uint32_t content_kind;
  uint32_t content_version;
  uint32_t reserved_u32;
  int64_t local_id;
  int64_t local_order;
  int64_t local_created_at_ms;
  int64_t server_sequence;
  int64_t server_sent_at_ms;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t client_message_id;
  xhim_v1_bytes_view_t server_message_id;
  xhim_v1_bytes_view_t sender_user_id;
  xhim_v1_bytes_view_t payload;
  xhim_v1_bytes_view_t fallback_text;
  /* Added after the initial v1 prefix; guard reads with struct_size. */
  xhim_v1_bytes_view_t content_type;
  /*
   * These fields consume the original v1 reserved tail, preserving the
   * 192-byte array stride. Mutation ID/time remain internal audit metadata.
   */
  uint64_t mutation_revision;
  uint64_t mutation_kind;
} xhim_v1_message_snapshot_t;

typedef struct xhim_v1_message_input {
  uint32_t struct_size;
  uint32_t abi_version;
  xhim_v1_bytes_view_t content_type;
  uint32_t content_version;
  uint32_t reserved_u32;
  xhim_v1_bytes_view_t payload;
  xhim_v1_bytes_view_t fallback_text;
  uint64_t reserved_u64[2];
} xhim_v1_message_input_t;

/*
 * One durable upload intent. Every input view is copied before create returns.
 * local_path is an SDK-sandbox-owned file and is never returned by a snapshot,
 * event, diagnostic, or wire payload. content_hash must contain the raw
 * 32-byte SHA-256 digest of the exact object. task_id/client_message_id may be
 * empty, in which case Core generates UUID v4 identities.
 */
typedef struct xhim_v1_media_upload_input {
  uint32_t struct_size;
  uint32_t abi_version;
  xhim_v1_bytes_view_t task_id;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t client_message_id;
  xhim_v1_bytes_view_t local_path;
  xhim_v1_bytes_view_t content_hash;
  uint64_t byte_size;
  xhim_v1_bytes_view_t mime_type;
  xhim_v1_bytes_view_t content_type;
  xhim_v1_bytes_view_t fallback_text;
  xhim_v1_bytes_view_t display_name;
  uint32_t width;
  uint32_t height;
  uint64_t duration_ms;
  xhim_v1_bytes_view_t waveform;
  int64_t local_created_at_ms;
  uint64_t reserved_u64[2];
} xhim_v1_media_upload_input_t;

/*
 * Stable server-owned media identity. All views are borrowed for the enclosing
 * media-task callback only. A wrapped_key is an account/recipient-wrapped
 * content key, never plaintext key material.
 */
typedef struct xhim_v1_media_ref_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t schema_version;
  uint32_t has_encryption;
  uint64_t byte_size;
  uint64_t storage_revision;
  xhim_v1_bytes_view_t media_id;
  xhim_v1_bytes_view_t content_hash;
  xhim_v1_bytes_view_t mime_type;
  xhim_v1_bytes_view_t encryption_scheme;
  xhim_v1_bytes_view_t encryption_key_id;
  xhim_v1_bytes_view_t encryption_nonce;
  xhim_v1_bytes_view_t encryption_wrapped_key;
  uint64_t reserved_u64[2];
} xhim_v1_media_ref_snapshot_t;

/*
 * One durable media download. media_ref is copied synchronously and must be a
 * schema-1 stable server identity previously received in a message/task.
 * cache_key is a flat SDK-sandbox-relative key (letters, digits, '.', '_',
 * '-'; max 128 bytes), never a path or server filename. Core stores the object
 * beneath the private cache root derived from storage_path and never exposes
 * an absolute path, signed URL, or bearer credential.
 */
typedef struct xhim_v1_media_download_input {
  uint32_t struct_size;
  uint32_t abi_version;
  xhim_v1_bytes_view_t task_id;
  xhim_v1_bytes_view_t cache_key;
  xhim_v1_media_ref_snapshot_t media_ref;
  int64_t local_created_at_ms;
  uint64_t reserved_u64[2];
} xhim_v1_media_download_input_t;

/*
 * Durable media-task snapshot. This structure intentionally excludes the
 * local file path, upload authorization, bearer token, signed URL, and
 * resumable-session credential. Every byte view, including nested media_ref
 * views, is borrowed only until xhim_v1_media_task_completion_callback returns;
 * platform facades must deep-copy values they retain.
 */
typedef struct xhim_v1_media_task_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t schema_version;
  int32_t state;
  int32_t direction;
  uint32_t message_enqueued;
  uint32_t failure_retryable;
  uint32_t has_media_ref;
  uint64_t byte_size;
  uint64_t bytes_transferred;
  uint64_t revision;
  uint64_t attempt_count;
  int64_t next_attempt_at_ms;
  int64_t created_at_ms;
  int64_t updated_at_ms;
  xhim_v1_bytes_view_t task_id;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t client_message_id;
  xhim_v1_bytes_view_t content_hash;
  xhim_v1_bytes_view_t mime_type;
  xhim_v1_bytes_view_t content_type;
  xhim_v1_bytes_view_t fallback_text;
  xhim_v1_bytes_view_t display_name;
  xhim_v1_bytes_view_t waveform;
  xhim_v1_bytes_view_t last_failure_code;
  uint32_t width;
  uint32_t height;
  uint64_t duration_ms;
  xhim_v1_media_ref_snapshot_t media_ref;
  uint64_t reserved_u64[2];
} xhim_v1_media_task_snapshot_t;

/*
 * Local message-search filter. query is required. conversation_id and
 * sender_user_id may be empty. content_types is an optional array of exact
 * stable content-type views; both the array and its views are copied before
 * this API returns.
 */
typedef struct xhim_v1_message_search_query {
  uint32_t struct_size;
  uint32_t abi_version;
  xhim_v1_bytes_view_t query;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t sender_user_id;
  uint32_t content_type_count;
  uint32_t reserved_u32;
  const xhim_v1_bytes_view_t *content_types;
  uint64_t reserved_u64[2];
} xhim_v1_message_search_query_t;

/*
 * Immutable keyset page. messages and every nested byte view are borrowed for
 * the callback duration. next_cursor is opaque binary data: copy it before the
 * callback returns and pass it unchanged to continue the same conversation.
 */
typedef struct xhim_v1_message_page {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t message_count;
  uint32_t has_more;
  xhim_v1_bytes_view_t next_cursor;
  const xhim_v1_message_snapshot_t *messages;
  uint64_t reserved_u64[2];
} xhim_v1_message_page_t;

/*
 * Immutable conversation-index snapshot. Byte views are borrowed for the
 * callback duration. Ordering keys remain private to Core; continue paging
 * only with the opaque cursor returned by xhim_v1_conversation_page_t.
 */
typedef struct xhim_v1_conversation_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t is_pinned;
  uint32_t reserved_u32;
  int64_t last_message_local_order;
  int64_t unread_count;
  int64_t read_sequence;
  int64_t updated_at_ms;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t last_message_client_id;
  xhim_v1_bytes_view_t last_message_preview;
  /*
   * These two fields consume the original v1 reserved tail, preserving this
   * array element's 112-byte stride for already-compiled clients.
   */
  uint64_t preference_revision;
  uint64_t preference_flags;
} xhim_v1_conversation_snapshot_t;

typedef struct xhim_v1_conversation_page {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t conversation_count;
  uint32_t has_more;
  xhim_v1_bytes_view_t next_cursor;
  const xhim_v1_conversation_snapshot_t *conversations;
  uint64_t reserved_u64[2];
} xhim_v1_conversation_page_t;

/*
 * Server-authoritative read watermark committed to the local conversation.
 * Byte views are borrowed only for the callback duration.
 */
typedef struct xhim_v1_conversation_read_receipt {
  uint32_t struct_size;
  uint32_t abi_version;
  int64_t read_sequence;
  int64_t unread_count;
  int64_t updated_at_ms;
  xhim_v1_bytes_view_t conversation_id;
  uint64_t reserved_u64[2];
} xhim_v1_conversation_read_receipt_t;

typedef struct xhim_v1_mark_all_conversations_read_input {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t max_changed_reads;
  uint32_t reserved_u32;
  xhim_v1_bytes_view_t mutation_id;
  uint64_t reserved_u64[2];
} xhim_v1_mark_all_conversations_read_input_t;

typedef struct xhim_v1_conversation_read_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  int64_t read_server_sequence;
  int64_t updated_at_ms;
  xhim_v1_bytes_view_t conversation_id;
  uint64_t reserved_u64[2];
} xhim_v1_conversation_read_snapshot_t;

/*
 * changed_reads and all nested views are borrowed for callback duration.
 * local_projection_complete=0 means Sync will converge omitted detail.
 */
typedef struct xhim_v1_mark_all_conversations_read_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t changed_read_count;
  uint32_t changed_reads_truncated;
  uint32_t idempotent_replay;
  uint32_t local_projection_complete;
  uint64_t changed_conversation_count;
  uint64_t scheduled_burn_count;
  const xhim_v1_conversation_read_snapshot_t *changed_reads;
  uint64_t reserved_u64[2];
} xhim_v1_mark_all_conversations_read_snapshot_t;

typedef struct xhim_v1_total_unread_count_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  int64_t total_unread_count;
  uint64_t reserved_u64[2];
} xhim_v1_total_unread_count_snapshot_t;

typedef struct xhim_v1_conversation_peer_read_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  int64_t read_server_sequence;
  int64_t updated_at_ms;
  uint64_t revision;
  xhim_v1_bytes_view_t reader_user_id;
  uint64_t reserved_u64[2];
} xhim_v1_conversation_peer_read_snapshot_t;

typedef struct xhim_v1_conversation_peer_read_page {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t read_count;
  uint32_t truncated;
  xhim_v1_bytes_view_t conversation_id;
  const xhim_v1_conversation_peer_read_snapshot_t *reads;
  uint64_t reserved_u64[2];
} xhim_v1_conversation_peer_read_page_t;

typedef struct xhim_v1_conversation_preference_input {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t pinned;
  uint32_t notifications_muted;
  uint64_t expected_revision;
  xhim_v1_bytes_view_t mutation_id;
  uint64_t reserved_u64[2];
} xhim_v1_conversation_preference_input_t;

typedef struct xhim_v1_conversation_preference_receipt {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t pinned;
  uint32_t notifications_muted;
  uint32_t changed;
  uint32_t reserved_u32;
  uint64_t revision;
  int64_t updated_at_ms;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t mutation_id;
  uint64_t reserved_u64[2];
} xhim_v1_conversation_preference_receipt_t;

/*
 * Local-only draft result. No field from this structure is serialized to the
 * service. Byte views are borrowed for the callback duration.
 */
typedef struct xhim_v1_conversation_draft_result {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t present;
  uint32_t changed;
  uint32_t content_version;
  uint32_t reserved_u32;
  int64_t updated_at_ms;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t content_type;
  xhim_v1_bytes_view_t payload;
  xhim_v1_bytes_view_t fallback_text;
  uint64_t reserved_u64[2];
} xhim_v1_conversation_draft_result_t;

typedef struct xhim_v1_friend_request_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  int32_t state;
  uint32_t reserved_u32;
  int64_t created_at_ms;
  int64_t updated_at_ms;
  xhim_v1_bytes_view_t request_id;
  xhim_v1_bytes_view_t client_request_id;
  xhim_v1_bytes_view_t from_user_id;
  xhim_v1_bytes_view_t to_user_id;
  xhim_v1_bytes_view_t introduction;
  uint64_t reserved_u64[2];
} xhim_v1_friend_request_snapshot_t;

typedef struct xhim_v1_friendship_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t active;
  uint32_t reserved_u32;
  int64_t created_at_ms;
  int64_t updated_at_ms;
  xhim_v1_bytes_view_t peer_user_id;
  uint64_t reserved_u64[2];
} xhim_v1_friendship_snapshot_t;

/*
 * Parallel directional remark data for xhim_v1_friendship_snapshot_t.
 * Keeping this separate preserves the v1 friendship array element stride.
 */
typedef struct xhim_v1_friendship_remark_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint64_t remark_revision;
  xhim_v1_bytes_view_t peer_user_id;
  xhim_v1_bytes_view_t remark;
  uint64_t reserved_u64[2];
} xhim_v1_friendship_remark_snapshot_t;

typedef struct xhim_v1_group_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t member_count;
  uint32_t joined;
  uint64_t revision;
  int64_t created_at_ms;
  int64_t updated_at_ms;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t title;
  xhim_v1_bytes_view_t owner_user_id;
  uint32_t join_approval_required;
  uint32_t reserved_u32;
  uint64_t reserved_u64[2];
} xhim_v1_group_snapshot_t;

/*
 * Profile data is intentionally a parallel array instead of a tail extension
 * on xhim_v1_group_snapshot_t. Group snapshots are returned as a contiguous
 * array, so changing their element size would break the v1 array stride.
 */
typedef struct xhim_v1_group_profile_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t avatar_url;
  xhim_v1_bytes_view_t announcement;
  xhim_v1_bytes_view_t description;
  uint64_t reserved_u64[2];
} xhim_v1_group_profile_snapshot_t;

typedef struct xhim_v1_group_member_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  int32_t role;
  int32_t state;
  int64_t joined_at_ms;
  int64_t updated_at_ms;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t user_id;
  int64_t muted_until_ms;
  uint64_t reserved_u64[2];
} xhim_v1_group_member_snapshot_t;

typedef struct xhim_v1_block_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t active;
  uint32_t reserved_u32;
  int64_t created_at_ms;
  int64_t updated_at_ms;
  xhim_v1_bytes_view_t user_id;
  xhim_v1_bytes_view_t blocked_user_id;
  uint64_t reserved_u64[2];
} xhim_v1_block_snapshot_t;

typedef struct xhim_v1_group_join_request_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  int32_t state;
  uint32_t reserved_u32;
  int64_t created_at_ms;
  int64_t updated_at_ms;
  xhim_v1_bytes_view_t request_id;
  xhim_v1_bytes_view_t client_request_id;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t requester_user_id;
  xhim_v1_bytes_view_t introduction;
  uint64_t reserved_u64[2];
} xhim_v1_group_join_request_snapshot_t;

/*
 * Exactly one typed pointer matches kind; all other typed pointers are null.
 * All item arrays, strings, and next_cursor are borrowed for the callback
 * duration. group_revision is populated only for GROUP_MEMBERS and fences paged
 * roster rendering against concurrent membership changes.
 *
 * For GROUPS, xhim_v1_social_page_get_group_profiles() exposes a parallel
 * profile array with item_count entries. The helper keeps the original
 * xhim_v1_group_snapshot_t array stride binary-compatible.
 * For FRIENDSHIPS, xhim_v1_social_page_get_friendship_remarks() likewise
 * exposes an item_count-sized directional remark array. Match both parallel
 * arrays by index and copy them before the page's borrowed lifetime ends.
 */
typedef struct xhim_v1_social_page {
  uint32_t struct_size;
  uint32_t abi_version;
  int32_t kind;
  uint32_t item_count;
  uint32_t has_more;
  uint32_t reserved_u32;
  uint64_t group_revision;
  xhim_v1_bytes_view_t next_cursor;
  const xhim_v1_friend_request_snapshot_t *friend_requests;
  const xhim_v1_friendship_snapshot_t *friendships;
  const xhim_v1_group_snapshot_t *groups;
  const xhim_v1_group_member_snapshot_t *group_members;
  const xhim_v1_block_snapshot_t *blocks;
  const xhim_v1_group_join_request_snapshot_t *group_join_requests;
  uint64_t reserved_u64[2];
} xhim_v1_social_page_t;

/*
 * Server-owned user profile. Every byte view in this section is borrowed only
 * for the duration of the completion callback that supplied it.
 */
typedef struct xhim_v1_user_profile_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  int64_t created_at_ms;
  int64_t updated_at_ms;
  xhim_v1_bytes_view_t user_id;
  xhim_v1_bytes_view_t display_name;
  xhim_v1_bytes_view_t avatar_url;
  xhim_v1_bytes_view_t bio;
  uint64_t reserved_u64[2];
} xhim_v1_user_profile_snapshot_t;

/*
 * One non-cursor batch response. profiles and missing_user_ids partition the
 * requested IDs exactly; missing IDs preserve request order. Both arrays and
 * all nested byte views are borrowed for the callback duration.
 */
typedef struct xhim_v1_user_profile_page {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t profile_count;
  uint32_t missing_user_id_count;
  const xhim_v1_user_profile_snapshot_t *profiles;
  const xhim_v1_bytes_view_t *missing_user_ids;
  uint64_t reserved_u64[2];
} xhim_v1_user_profile_page_t;

/*
 * field_mask makes empty-string clearing unambiguous: an enabled field with a
 * zero-length view clears it; a field absent from the mask is unchanged.
 */
typedef struct xhim_v1_profile_update_input {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t field_mask;
  uint32_t reserved_u32;
  xhim_v1_bytes_view_t display_name;
  xhim_v1_bytes_view_t avatar_url;
  xhim_v1_bytes_view_t bio;
  uint64_t reserved_u64[2];
} xhim_v1_profile_update_input_t;

typedef struct xhim_v1_direct_conversation_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t created;
  uint32_t participant_count;
  int64_t created_at_ms;
  int64_t updated_at_ms;
  xhim_v1_bytes_view_t conversation_id;
  const xhim_v1_bytes_view_t *participant_user_ids;
  xhim_v1_user_profile_snapshot_t peer_profile;
  uint64_t reserved_u64[2];
} xhim_v1_direct_conversation_snapshot_t;

/*
 * token is copied before the API returns and is never echoed in callbacks,
 * diagnostics, events, or logs.
 */
typedef struct xhim_v1_push_device_input {
  uint32_t struct_size;
  uint32_t abi_version;
  int32_t platform;
  uint32_t reserved_u32;
  xhim_v1_bytes_view_t device_id;
  xhim_v1_bytes_view_t token;
  xhim_v1_bytes_view_t environment;
  xhim_v1_bytes_view_t locale;
  uint64_t reserved_u64[2];
} xhim_v1_push_device_input_t;

typedef struct xhim_v1_push_device_registration_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t enabled;
  uint32_t token_reassigned;
  int64_t updated_at_ms;
  uint32_t device_limit;
  uint32_t evicted_count;
  xhim_v1_bytes_view_t device_id;
  uint64_t reserved_u64[2];
} xhim_v1_push_device_registration_snapshot_t;

typedef struct xhim_v1_push_device_disable_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t disabled;
  uint32_t changed;
  xhim_v1_bytes_view_t device_id;
  uint64_t reserved_u64[2];
} xhim_v1_push_device_disable_snapshot_t;

/*
 * mutation_id is caller-owned, copied before return, and preserved as the
 * service idempotency identity. Reusing an ID with different input is an
 * IDEMPOTENCY_CONFLICT.
 */
typedef struct xhim_v1_send_friend_request_input {
  uint32_t struct_size;
  uint32_t abi_version;
  xhim_v1_bytes_view_t mutation_id;
  xhim_v1_bytes_view_t to_user_id;
  xhim_v1_bytes_view_t introduction;
  uint64_t reserved_u64[2];
} xhim_v1_send_friend_request_input_t;

typedef struct xhim_v1_resolve_friend_request_input {
  uint32_t struct_size;
  uint32_t abi_version;
  int32_t decision;
  uint32_t reserved_u32;
  xhim_v1_bytes_view_t mutation_id;
  xhim_v1_bytes_view_t request_id;
  uint64_t reserved_u64[2];
} xhim_v1_resolve_friend_request_input_t;

/*
 * All byte views are deep-copied before the API returns. mutation_id must be
 * stable for retries of the exact same peer deletion.
 */
typedef struct xhim_v1_delete_friendship_input {
  uint32_t struct_size;
  uint32_t abi_version;
  xhim_v1_bytes_view_t mutation_id;
  xhim_v1_bytes_view_t peer_user_id;
  uint64_t reserved_u64[2];
} xhim_v1_delete_friendship_input_t;

typedef struct xhim_v1_set_friend_remark_input {
  uint32_t struct_size;
  uint32_t abi_version;
  uint64_t expected_revision;
  xhim_v1_bytes_view_t mutation_id;
  xhim_v1_bytes_view_t peer_user_id;
  /* Empty clears the current account's directional remark. */
  xhim_v1_bytes_view_t remark;
  uint64_t reserved_u64[2];
} xhim_v1_set_friend_remark_input_t;

typedef struct xhim_v1_publish_presence_input {
  uint32_t struct_size;
  uint32_t abi_version;
  int32_t status;
  uint32_t ttl_ms;
  uint64_t reserved_u64[2];
} xhim_v1_publish_presence_input_t;

typedef struct xhim_v1_publish_typing_input {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t is_typing;
  uint32_t ttl_ms;
  xhim_v1_bytes_view_t conversation_id;
  uint64_t reserved_u64[2];
} xhim_v1_publish_typing_input_t;

typedef struct xhim_v1_create_group_input {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t member_user_id_count;
  uint32_t reserved_u32;
  xhim_v1_bytes_view_t mutation_id;
  xhim_v1_bytes_view_t title;
  const xhim_v1_bytes_view_t *member_user_ids;
  uint64_t reserved_u64[2];
} xhim_v1_create_group_input_t;

typedef struct xhim_v1_change_group_members_input {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t add_user_id_count;
  uint32_t remove_user_id_count;
  uint64_t expected_revision;
  xhim_v1_bytes_view_t mutation_id;
  xhim_v1_bytes_view_t conversation_id;
  const xhim_v1_bytes_view_t *add_user_ids;
  const xhim_v1_bytes_view_t *remove_user_ids;
  uint64_t reserved_u64[2];
} xhim_v1_change_group_members_input_t;

/*
 * Both byte views are deep-copied before return. expected_revision is an
 * exact server CAS fence and must be nonzero.
 */
typedef struct xhim_v1_leave_group_input {
  uint32_t struct_size;
  uint32_t abi_version;
  uint64_t expected_revision;
  xhim_v1_bytes_view_t mutation_id;
  xhim_v1_bytes_view_t conversation_id;
  uint64_t reserved_u64[2];
} xhim_v1_leave_group_input_t;

typedef struct xhim_v1_dismiss_group_input {
  uint32_t struct_size;
  uint32_t abi_version;
  uint64_t expected_revision;
  xhim_v1_bytes_view_t mutation_id;
  xhim_v1_bytes_view_t conversation_id;
  uint64_t reserved_u64[2];
} xhim_v1_dismiss_group_input_t;

typedef struct xhim_v1_set_block_input {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t active;
  uint32_t reserved_u32;
  xhim_v1_bytes_view_t mutation_id;
  xhim_v1_bytes_view_t blocked_user_id;
  uint64_t reserved_u64[2];
} xhim_v1_set_block_input_t;

typedef struct xhim_v1_request_group_join_input {
  uint32_t struct_size;
  uint32_t abi_version;
  xhim_v1_bytes_view_t mutation_id;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t introduction;
  uint64_t reserved_u64[2];
} xhim_v1_request_group_join_input_t;

typedef struct xhim_v1_resolve_group_join_input {
  uint32_t struct_size;
  uint32_t abi_version;
  int32_t decision;
  uint32_t reserved_u32;
  xhim_v1_bytes_view_t mutation_id;
  xhim_v1_bytes_view_t request_id;
  uint64_t reserved_u64[2];
} xhim_v1_resolve_group_join_input_t;

typedef struct xhim_v1_change_group_governance_input {
  uint32_t struct_size;
  uint32_t abi_version;
  int32_t action;
  uint32_t admin;
  uint64_t expected_revision;
  int64_t muted_until_ms;
  uint32_t join_approval_required;
  uint32_t reserved_u32;
  xhim_v1_bytes_view_t mutation_id;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t target_user_id;
  xhim_v1_bytes_view_t title;
  xhim_v1_bytes_view_t avatar_url;
  xhim_v1_bytes_view_t announcement;
  xhim_v1_bytes_view_t description;
  uint64_t reserved_u64[2];
} xhim_v1_change_group_governance_input_t;

/*
 * All input byte views below are deep-copied before the API returns. History
 * pagination is newest-first by server sequence; zero before_server_sequence
 * starts at the current server high-watermark and zero limit selects 50.
 */
typedef struct xhim_v1_message_history_query {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t limit;
  uint32_t reserved_u32;
  uint64_t before_server_sequence;
  xhim_v1_bytes_view_t conversation_id;
  uint64_t reserved_u64[2];
} xhim_v1_message_history_query_t;

typedef struct xhim_v1_delete_message_for_self_input {
  uint32_t struct_size;
  uint32_t abi_version;
  uint64_t expected_revision;
  xhim_v1_bytes_view_t mutation_id;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t server_message_id;
  uint64_t reserved_u64[2];
} xhim_v1_delete_message_for_self_input_t;

typedef struct xhim_v1_clear_conversation_input {
  uint32_t struct_size;
  uint32_t abi_version;
  uint64_t through_server_sequence;
  uint64_t expected_revision;
  xhim_v1_bytes_view_t mutation_id;
  xhim_v1_bytes_view_t conversation_id;
  uint64_t reserved_u64[2];
} xhim_v1_clear_conversation_input_t;

typedef struct xhim_v1_hide_conversation_input {
  uint32_t struct_size;
  uint32_t abi_version;
  uint64_t expected_revision;
  xhim_v1_bytes_view_t mutation_id;
  xhim_v1_bytes_view_t conversation_id;
  uint64_t reserved_u64[2];
} xhim_v1_hide_conversation_input_t;

/*
 * Snapshots, arrays, and nested byte views below are borrowed only for the
 * duration of the completion callback that supplied them.
 */
typedef struct xhim_v1_message_visibility_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t deleted;
  uint32_t reserved_u32;
  int64_t server_sequence;
  uint64_t revision;
  int64_t updated_at_ms;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t user_id;
  xhim_v1_bytes_view_t server_message_id;
  xhim_v1_bytes_view_t mutation_id;
  uint64_t reserved_u64[2];
} xhim_v1_message_visibility_snapshot_t;

typedef struct xhim_v1_conversation_view_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  int64_t cleared_through_server_sequence;
  int64_t hidden_through_server_sequence;
  uint64_t revision;
  int64_t updated_at_ms;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t user_id;
  xhim_v1_bytes_view_t mutation_id;
  uint64_t reserved_u64[2];
} xhim_v1_conversation_view_snapshot_t;

typedef struct xhim_v1_message_history_page {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t message_count;
  uint32_t has_more;
  uint32_t has_view;
  uint32_t reserved_u32;
  uint64_t next_before_server_sequence;
  uint64_t latest_server_sequence;
  const xhim_v1_message_snapshot_t *messages;
  xhim_v1_conversation_view_snapshot_t view;
  uint64_t reserved_u64[2];
} xhim_v1_message_history_page_t;

typedef struct xhim_v1_message_visibility_mutation_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t changed;
  uint32_t reserved_u32;
  xhim_v1_message_visibility_snapshot_t visibility;
  uint64_t reserved_u64[2];
} xhim_v1_message_visibility_mutation_snapshot_t;

typedef struct xhim_v1_conversation_view_mutation_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t changed;
  uint32_t reserved_u32;
  xhim_v1_conversation_view_snapshot_t view;
  uint64_t reserved_u64[2];
} xhim_v1_conversation_view_mutation_snapshot_t;

/*
 * Device-session snapshots are server authoritative. Arrays and every byte
 * view are borrowed only for the completion callback duration.
 */
typedef struct xhim_v1_device_session_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  int32_t platform;
  uint32_t active;
  uint32_t current;
  uint32_t reserved_u32;
  int64_t created_at_ms;
  int64_t last_seen_at_ms;
  int64_t expires_at_ms;
  int64_t revoked_at_ms;
  xhim_v1_bytes_view_t session_id;
  xhim_v1_bytes_view_t device_id;
  xhim_v1_bytes_view_t revoke_reason;
  uint64_t reserved_u64[2];
} xhim_v1_device_session_snapshot_t;

typedef struct xhim_v1_device_session_page {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t session_count;
  uint32_t max_sessions_per_user;
  const xhim_v1_device_session_snapshot_t *sessions;
  xhim_v1_bytes_view_t multi_login_policy;
  uint64_t reserved_u64[2];
} xhim_v1_device_session_page_t;

/*
 * Both byte views are deep-copied before the API returns. mutation_id is the
 * stable idempotency identity for retries of the same session revocation.
 */
typedef struct xhim_v1_revoke_device_session_input {
  uint32_t struct_size;
  uint32_t abi_version;
  xhim_v1_bytes_view_t mutation_id;
  xhim_v1_bytes_view_t session_id;
  uint64_t reserved_u64[2];
} xhim_v1_revoke_device_session_input_t;

typedef struct xhim_v1_device_session_revocation_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t changed;
  uint32_t reserved_u32;
  xhim_v1_device_session_snapshot_t session;
  uint64_t reserved_u64[2];
} xhim_v1_device_session_revocation_snapshot_t;

/*
 * Synchronous policy getters use inline, caller-owned storage: no pointer,
 * token, endpoint, or borrowed lifetime escapes the call.
 */
typedef struct xhim_v1_device_session_value {
  uint32_t struct_size;
  uint32_t abi_version;
  int32_t platform;
  uint32_t active;
  uint32_t current;
  uint32_t reserved_u32;
  int64_t created_at_ms;
  int64_t last_seen_at_ms;
  int64_t expires_at_ms;
  int64_t revoked_at_ms;
  xhim_v1_inline_utf8_512_t session_id;
  xhim_v1_inline_utf8_512_t device_id;
  xhim_v1_inline_utf8_512_t revoke_reason;
  uint32_t reserved_u32_tail;
  uint64_t reserved_u64[2];
} xhim_v1_device_session_value_t;

typedef struct xhim_v1_device_session_policy_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t schema_version;
  uint32_t max_sessions_per_user;
  xhim_v1_device_session_value_t current_session;
  xhim_v1_inline_utf8_128_t multi_login_policy;
  uint32_t reserved_u32;
  uint64_t reserved_u64[2];
} xhim_v1_device_session_policy_snapshot_t;

typedef struct xhim_v1_friend_request_resolution_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t has_friendship;
  uint32_t reserved_u32;
  xhim_v1_friend_request_snapshot_t request;
  xhim_v1_friendship_snapshot_t friendship;
  uint64_t reserved_u64[2];
} xhim_v1_friend_request_resolution_snapshot_t;

/*
 * The friendship and its byte views are borrowed for callback duration.
 * Copy any data needed after the callback returns.
 */
typedef struct xhim_v1_friendship_deletion_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t idempotent_replay;
  uint32_t reserved_u32;
  xhim_v1_friendship_snapshot_t friendship;
  uint64_t reserved_u64[2];
} xhim_v1_friendship_deletion_snapshot_t;

typedef struct xhim_v1_friendship_remark_change_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t idempotent_replay;
  uint32_t reserved_u32;
  xhim_v1_friendship_snapshot_t friendship;
  xhim_v1_friendship_remark_snapshot_t remark;
  uint64_t reserved_u64[2];
} xhim_v1_friendship_remark_change_snapshot_t;

typedef struct xhim_v1_presence_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  int32_t status;
  uint32_t reserved_u32;
  uint64_t sequence;
  int64_t expires_at_ms;
  xhim_v1_bytes_view_t user_id;
  uint64_t reserved_u64[2];
} xhim_v1_presence_snapshot_t;

typedef struct xhim_v1_typing_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t is_typing;
  uint32_t reserved_u32;
  uint64_t sequence;
  int64_t expires_at_ms;
  xhim_v1_bytes_view_t conversation_id;
  xhim_v1_bytes_view_t user_id;
  uint64_t reserved_u64[2];
} xhim_v1_typing_snapshot_t;

/*
 * members and every nested byte view are borrowed for callback duration.
 * group_profile is parallel to group to preserve the older group array stride.
 */
typedef struct xhim_v1_group_change_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t member_count;
  uint32_t reserved_u32;
  xhim_v1_group_snapshot_t group;
  xhim_v1_group_profile_snapshot_t group_profile;
  const xhim_v1_group_member_snapshot_t *members;
  uint64_t reserved_u64[2];
} xhim_v1_group_change_snapshot_t;

/*
 * group_change, members, and all nested byte views are borrowed for callback
 * duration. idempotent_replay means the service returned the previously
 * committed result; Core still applies the same revision-fenced projection.
 */
typedef struct xhim_v1_group_lifecycle_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t idempotent_replay;
  uint32_t reserved_u32;
  xhim_v1_group_change_snapshot_t group_change;
  uint64_t reserved_u64[2];
} xhim_v1_group_lifecycle_snapshot_t;

typedef struct xhim_v1_group_join_mutation_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t has_group_change;
  uint32_t reserved_u32;
  xhim_v1_group_join_request_snapshot_t request;
  xhim_v1_group_change_snapshot_t group_change;
  uint64_t reserved_u64[2];
} xhim_v1_group_join_mutation_snapshot_t;

/*
 * Versioned operational policy copied during client_create. Zero-valued
 * settings select the SDK default. Bootstrap endpoints and TLS trust are not
 * accepted from ordinary App code: the Product Adapter owns those fail-closed
 * security decisions and verifies the signed EndpointBundle.
 */
typedef struct xhim_v1_runtime_policy {
  uint32_t struct_size;
  /* 0 selects all defaults; 1 enables the fields below. */
  uint32_t schema_version;
  uint32_t request_timeout_ms;
  uint32_t sync_page_size;
  uint32_t reconnect_initial_delay_ms;
  uint32_t reconnect_max_delay_ms;
  uint32_t max_reconnect_attempts;
  uint32_t reserved_u32;
} xhim_v1_runtime_policy_t;

/*
 * Optional customer deployment selected when the client is created.
 *
 * Only the bootstrap URL and the public EndpointBundle verification key are
 * accepted. API, WebSocket, upload, and media endpoints are returned by the
 * bootstrap service in a signed EndpointBundle and remain subject to the
 * SDK's HTTPS/WSS and expiry checks. This makes one binary SDK reusable for
 * customer-hosted deployments without exposing TLS bypass controls.
 */
typedef struct xhim_v1_deployment_config {
  uint32_t struct_size;
  /* 0 selects the Product Adapter build defaults; 1 enables this structure. */
  uint32_t schema_version;
  xhim_v1_bytes_view_t bootstrap_url;
  xhim_v1_bytes_view_t endpoint_signing_key_id;
  xhim_v1_bytes_view_t endpoint_signing_public_key_base64;
  uint64_t reserved_u64[2];
} xhim_v1_deployment_config_t;

typedef struct xhim_v1_client_config {
  uint32_t struct_size;
  uint32_t abi_version;
  xhim_v1_bytes_view_t app_id;
  xhim_v1_bytes_view_t storage_path;
  /* 0 selects XHIM_V1_DEFAULT_EVENT_QUEUE_CAPACITY. */
  uint32_t event_queue_capacity;
  /* Bitwise OR of XHIM_V1_CLIENT_FLAG_* values. Zero is production mode. */
  uint32_t flags;
  xhim_v1_runtime_policy_t runtime_policy;
  xhim_v1_deployment_config_t deployment;
} xhim_v1_client_config_t;

/*
 * Non-sensitive, negotiated protocol state for the current authenticated
 * account epoch. All strings are length-prefixed inline UTF-8 copies.
 */
typedef struct xhim_v1_compatibility_snapshot {
  uint32_t struct_size;
  uint32_t abi_version;
  uint32_t schema_version;
  uint32_t client_protocol_version;
  uint32_t server_protocol_version;
  uint32_t minimum_client_protocol_version;
  uint32_t required_capability_count;
  uint32_t server_capability_count;
  xhim_v1_inline_utf8_128_t client_sdk_version;
  xhim_v1_inline_utf8_128_t server_version;
  xhim_v1_inline_utf8_128_t
      required_capabilities[XHIM_V1_MAX_COMPATIBILITY_CAPABILITIES];
  xhim_v1_inline_utf8_128_t
      server_capabilities[XHIM_V1_MAX_COMPATIBILITY_CAPABILITIES];
  uint64_t reserved_u64[4];
} xhim_v1_compatibility_snapshot_t;

/*
 * Non-sensitive point-in-time operational counters. The snapshot never
 * contains account/user/conversation/message/task IDs, paths, endpoints,
 * tokens, cursors, payloads, or error text. Counters are monotonic for the
 * lifetime of one client and may wrap after UINT64_MAX.
 */
typedef struct xhim_v1_diagnostics_snapshot {
  uint32_t struct_size;
  uint32_t schema_version;
  int32_t client_state;
  uint32_t backend_configured;
  uint32_t closing;
  uint32_t ffi_callback_running;
  uint32_t engine_callback_running;
  uint32_t state_pump_scheduled;
  uint64_t account_epoch;
  uint64_t connection_generation;
  uint64_t lifecycle_revision;
  uint64_t permit_generation;
  uint64_t active_requests;
  uint64_t event_subscribers;
  uint64_t ffi_callback_capacity;
  uint64_t ffi_pending_events;
  uint64_t ffi_completion_reservations;
  uint64_t engine_callback_normal_capacity;
  uint64_t engine_callback_normal_pending;
  uint64_t engine_callback_normal_reserved;
  uint64_t engine_callback_control_capacity;
  uint64_t engine_callback_control_pending;
  uint64_t engine_callback_control_reserved;
  uint64_t engine_state_pump_capacity;
  uint64_t engine_state_pump_pending;
  uint64_t engine_state_subscribers;
  uint64_t engine_media_task_subscribers;
  uint64_t state_relay_capacity;
  uint64_t state_relay_pending;
  uint64_t engine_state_mailbox_capacity;
  uint64_t engine_state_mailbox_pending;
  uint64_t ffi_event_rejections;
  uint64_t ffi_completion_rejections;
  uint64_t ffi_discarded_events;
  uint64_t ffi_discarded_completions;
  uint64_t state_relay_coalesced;
  uint64_t engine_callback_normal_rejections;
  uint64_t engine_callback_control_rejections;
  uint64_t engine_state_pump_rejections;
  uint64_t engine_state_mailbox_coalesced;
  uint64_t reserved_u64[8];
} xhim_v1_diagnostics_snapshot_t;

/*
 * Configuration copied synchronously by xhim_v1_offline_reader_create().
 *
 * database_key is raw binary key material. It must contain 32-64 bytes when
 * present, and is required when require_database_encryption is 1. Core copies
 * the key for the duration of open, securely clears its internal copy, and
 * never retains the caller's view.
 */
typedef struct xhim_v1_offline_reader_config {
  uint32_t struct_size;
  uint32_t abi_version;
  xhim_v1_bytes_view_t database_path;
  xhim_v1_bytes_view_t account_id;
  xhim_v1_bytes_view_t database_key;
  uint32_t require_database_encryption;
  uint32_t reserved_u32;
  uint64_t reserved_u64[2];
} xhim_v1_offline_reader_config_t;

/*
 * Callback contract:
 *
 * - Each client owns one private serial callback thread. Event and completion
 *   callbacks for that client run on that thread, never on the Core Actor.
 * - A callback can race the return of the API that scheduled it, but a
 *   successful API stores out_request_id before that callback can begin.
 * - Callbacks must return promptly. They may enqueue another asynchronous SDK
 *   operation, but must not block waiting for that operation's callback; doing
 *   so would block the client's only callback thread.
 * - All byte views supplied to callbacks are borrowed and remain valid only
 *   until that callback returns. A platform wrapper must decode or copy them
 *   before returning.
 */
typedef void(XHIM_V1_CALL *xhim_v1_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    xhim_v1_bytes_view_t result);

typedef void(XHIM_V1_CALL *xhim_v1_event_callback)(
    void *user_data, const xhim_v1_event_t *event);

typedef void(XHIM_V1_CALL *xhim_v1_message_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_message_snapshot_t *message);

typedef void(XHIM_V1_CALL *xhim_v1_media_task_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_media_task_snapshot_t *task);

typedef void(XHIM_V1_CALL *xhim_v1_message_page_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_message_page_t *page);

typedef void(XHIM_V1_CALL *xhim_v1_conversation_page_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_conversation_page_t *page);

typedef void(XHIM_V1_CALL *xhim_v1_conversation_read_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_conversation_read_receipt_t *receipt);

typedef void(
    XHIM_V1_CALL *xhim_v1_mark_all_conversations_read_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_mark_all_conversations_read_snapshot_t *result);

typedef void(XHIM_V1_CALL *xhim_v1_total_unread_count_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_total_unread_count_snapshot_t *result);

typedef void(
    XHIM_V1_CALL *xhim_v1_conversation_peer_read_page_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_conversation_peer_read_page_t *page);

typedef void(
    XHIM_V1_CALL *xhim_v1_conversation_preference_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_conversation_preference_receipt_t *receipt);

typedef void(XHIM_V1_CALL *xhim_v1_conversation_draft_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_conversation_draft_result_t *result);

typedef void(XHIM_V1_CALL *xhim_v1_social_page_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_social_page_t *page);

typedef void(XHIM_V1_CALL *xhim_v1_user_profile_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_user_profile_snapshot_t *profile);

typedef void(XHIM_V1_CALL *xhim_v1_user_profile_page_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_user_profile_page_t *page);

typedef void(XHIM_V1_CALL *xhim_v1_direct_conversation_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_direct_conversation_snapshot_t *conversation);

typedef void(
    XHIM_V1_CALL *xhim_v1_push_device_registration_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_push_device_registration_snapshot_t *registration);

typedef void(
    XHIM_V1_CALL *xhim_v1_push_device_disable_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_push_device_disable_snapshot_t *result);

typedef void(XHIM_V1_CALL *xhim_v1_friend_request_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_friend_request_snapshot_t *request);

typedef void(
    XHIM_V1_CALL *xhim_v1_friend_request_resolution_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_friend_request_resolution_snapshot_t *result);

typedef void(
    XHIM_V1_CALL *xhim_v1_friendship_deletion_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_friendship_deletion_snapshot_t *result);

typedef void(
    XHIM_V1_CALL *xhim_v1_friendship_remark_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_friendship_remark_change_snapshot_t *result);

typedef void(XHIM_V1_CALL *xhim_v1_presence_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_presence_snapshot_t *result);

typedef void(XHIM_V1_CALL *xhim_v1_typing_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_typing_snapshot_t *result);

typedef void(XHIM_V1_CALL *xhim_v1_group_change_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_group_change_snapshot_t *change);

typedef void(XHIM_V1_CALL *xhim_v1_group_lifecycle_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_group_lifecycle_snapshot_t *result);

typedef void(XHIM_V1_CALL *xhim_v1_block_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_block_snapshot_t *block);

typedef void(XHIM_V1_CALL *xhim_v1_group_join_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_group_join_mutation_snapshot_t *result);

typedef void(XHIM_V1_CALL *xhim_v1_message_history_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_message_history_page_t *page);

typedef void(
    XHIM_V1_CALL *xhim_v1_message_visibility_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_message_visibility_mutation_snapshot_t *result);

typedef void(
    XHIM_V1_CALL *xhim_v1_conversation_view_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_conversation_view_mutation_snapshot_t *result);

typedef void(XHIM_V1_CALL *xhim_v1_device_session_page_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_device_session_page_t *page);

typedef void(
    XHIM_V1_CALL *xhim_v1_device_session_revocation_completion_callback)(
    void *user_data, uint64_t request_id, const xhim_v1_error_t *error,
    const xhim_v1_device_session_revocation_snapshot_t *result);

XHIM_V1_API uint32_t XHIM_V1_CALL xhim_v1_abi_version(void);
XHIM_V1_API const char *XHIM_V1_CALL xhim_v1_version_string(void);
XHIM_V1_API const char *XHIM_V1_CALL xhim_v1_source_commit(void);
XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_social_page_get_group_profiles(
    const xhim_v1_social_page_t *page,
    const xhim_v1_group_profile_snapshot_t **out_profiles,
    uint32_t *out_count);

XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_social_page_get_friendship_remarks(
    const xhim_v1_social_page_t *page,
    const xhim_v1_friendship_remark_snapshot_t **out_remarks,
    uint32_t *out_count);
XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_user_profile_page_get_missing_user_ids(
    const xhim_v1_user_profile_page_t *page,
    const xhim_v1_bytes_view_t **out_user_ids, uint32_t *out_count);
XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_direct_conversation_get_participant_user_ids(
    const xhim_v1_direct_conversation_snapshot_t *conversation,
    const xhim_v1_bytes_view_t **out_user_ids, uint32_t *out_count);

/*
 * Synchronous, query-only access to an existing current-schema account
 * database. create() opens SQLite read-only, enables query_only, validates the
 * bound account, and never creates or migrates a schema.
 *
 * Every page and nested byte view returned below is borrowed from reader. It
 * remains valid only until the next API call using the same reader, or until
 * destroy. Copy required values before then.
 *
 * A reader invokes no callbacks and never creates a request_id. All operations
 * may block on disk I/O and must run off the UI thread. Calls on one reader,
 * including destroy, must be externally serialized; reentrant or concurrent
 * queries fail with XHIM_V1_STATUS_INVALID_STATE.
 *
 * For each synchronous list/search call, the caller must initialize
 * out_page->struct_size to its allocated byte capacity. Core requires the
 * documented non-reserved prefix, writes at most min(struct_size,
 * sizeof(current SDK structure)), and preserves struct_size as that caller
 * capacity. This makes future tail extensions safe for clients built with an
 * older header. A failed call clears only the known writable prefix.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_offline_reader_create(
    const xhim_v1_offline_reader_config_t *config,
    xhim_v1_offline_reader_t **out_reader);
XHIM_V1_API void XHIM_V1_CALL
xhim_v1_offline_reader_destroy(xhim_v1_offline_reader_t *reader);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_offline_reader_list_messages(
    xhim_v1_offline_reader_t *reader,
    xhim_v1_bytes_view_t conversation_id, xhim_v1_bytes_view_t cursor,
    uint32_t limit, xhim_v1_message_page_t *out_page);
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_offline_reader_search_messages(
    xhim_v1_offline_reader_t *reader,
    const xhim_v1_message_search_query_t *query,
    xhim_v1_bytes_view_t cursor, uint32_t limit,
    xhim_v1_message_page_t *out_page);
XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_offline_reader_list_conversations(
    xhim_v1_offline_reader_t *reader, xhim_v1_bytes_view_t cursor,
    uint32_t limit, xhim_v1_conversation_page_t *out_page);

XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_offline_reader_list_friend_requests(
    xhim_v1_offline_reader_t *reader, xhim_v1_bytes_view_t cursor,
    uint32_t limit, xhim_v1_social_page_t *out_page);
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_offline_reader_list_friendships(
    xhim_v1_offline_reader_t *reader, xhim_v1_bytes_view_t cursor,
    uint32_t limit, xhim_v1_social_page_t *out_page);
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_offline_reader_list_groups(
    xhim_v1_offline_reader_t *reader, xhim_v1_bytes_view_t cursor,
    uint32_t limit, xhim_v1_social_page_t *out_page);
XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_offline_reader_list_group_members(
    xhim_v1_offline_reader_t *reader,
    xhim_v1_bytes_view_t conversation_id, xhim_v1_bytes_view_t cursor,
    uint32_t limit, xhim_v1_social_page_t *out_page);
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_offline_reader_list_blocks(
    xhim_v1_offline_reader_t *reader, xhim_v1_bytes_view_t cursor,
    uint32_t limit, xhim_v1_social_page_t *out_page);
XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_offline_reader_list_group_join_requests(
    xhim_v1_offline_reader_t *reader, xhim_v1_bytes_view_t cursor,
    uint32_t limit, xhim_v1_social_page_t *out_page);

/*
 * Immediate return values only report validation/enqueue failures.
 * A completion callback is required for every asynchronous request.
 *
 * An accepted request completes exactly once unless client_destroy begins
 * first. Destroy cancels callback work that has not started; it never starts a
 * new callback after destroy returns. Like other asynchronous SDK contracts,
 * this guarantee assumes the documented supported resource envelope; the
 * current 0.x dispatcher does not provide allocation-free recovery from
 * process-wide memory exhaustion.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_create(
    const xhim_v1_client_config_t *config, xhim_v1_client_t **out_client);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_start(
    xhim_v1_client_t *client, xhim_v1_completion_callback callback,
    void *user_data, uint64_t *out_request_id);

/*
 * Production mode fails closed with
 * XHIM_V1_STATUS_BACKEND_NOT_CONFIGURED until a product backend adapter is
 * present. LOCAL_PREVIEW may be used only by tests and the repository CLI.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_login(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t user_id,
    xhim_v1_bytes_view_t access_token, xhim_v1_completion_callback callback,
    void *user_data, uint64_t *out_request_id);

/*
 * Rotates credentials only for the canonical account retained by a
 * CREDENTIAL_REQUIRED session. The host cannot supply a replacement account,
 * so credential refresh cannot silently switch the active storage profile.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_update_credential(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t access_token,
    xhim_v1_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

/*
 * Best-effort, idempotent reachability hint for an OS network monitor. This
 * synchronous call performs no network I/O and invokes no callback. It may
 * wake only the current fenced reconnect timer; it never bypasses retry
 * limits, Retry-After, credentials, TLS, logout, or shutdown. Calling it while
 * a live client has no pending reconnect is a successful no-op.
 */
XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_client_notify_network_available(xhim_v1_client_t *client);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_logout(
    xhim_v1_client_t *client, xhim_v1_completion_callback callback,
    void *user_data, uint64_t *out_request_id);

/*
 * client_message_id may be empty, in which case Core generates UUID v4.
 * A caller-supplied value must be globally unique within the storage profile;
 * retries of one logical send must reuse the same ID and immutable payload.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_send_text(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t conversation_id,
    xhim_v1_bytes_view_t client_message_id, xhim_v1_bytes_view_t text,
    xhim_v1_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

/*
 * Sends one immutable versioned envelope. content_type is a stable built-in
 * XHIM_V1_CONTENT_TYPE_* value or a product-owned namespace. payload is opaque
 * binary data up to the documented limit; fallback_text must be valid UTF-8.
 * Large media bytes are uploaded with xhim_v1_client_create_media_upload and
 * the dependent envelope carries only a stable MediaRef descriptor.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_send_message(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t conversation_id,
    xhim_v1_bytes_view_t client_message_id,
    const xhim_v1_message_input_t *message,
    xhim_v1_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

/*
 * Persists an upload task and its dependent message intent. An OK completion
 * means the durable task was accepted (or replayed idempotently), not that the
 * upload completed. Observe MEDIA_TASK_UPDATED or query get_media_task until
 * COMPLETED/FAILED/CANCELLED. Product mode without a Media adapter rejects
 * admission instead of silently sending a local path.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_create_media_upload(
    xhim_v1_client_t *client,
    const xhim_v1_media_upload_input_t *input,
    xhim_v1_media_task_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

/*
 * Persists a resumable authenticated download. OK means durable admission,
 * not completion. The same get/cancel APIs and MEDIA_TASK_UPDATED event apply.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_create_media_download(
    xhim_v1_client_t *client,
    const xhim_v1_media_download_input_t *input,
    xhim_v1_media_task_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_get_media_task(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t task_id,
    xhim_v1_media_task_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

/*
 * Applies an account-Epoch and SQLite revision-fenced cancellation. Repeating
 * cancellation of an already-cancelled task succeeds with the same snapshot.
 * A completed task returns INVALID_STATE.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_cancel_media_task(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t task_id,
    xhim_v1_media_task_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

/*
 * Opens an atomically committed private-cache object without returning its
 * path. This synchronous operation validates the flat cache key and complete
 * MediaRef, then the product MediaTransport opens a no-follow native handle,
 * verifies regular-file/size/SHA-256 integrity, and transfers handle ownership
 * to out_reader. Run open and all reads off the UI thread.
 *
 * The reader may outlive client. Calls using one reader, including destroy,
 * must be externally serialized. A platform reads bounded chunks until
 * out_bytes_read is zero; stopping that loop is cancellation and needs no
 * Core request ID. Products without a secure cache-reader port return
 * XHIM_V1_STATUS_UNSUPPORTED.
 */
XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_client_open_media_cache_reader(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t cache_key,
    const xhim_v1_media_ref_snapshot_t *media_ref,
    xhim_v1_media_cache_reader_t **out_reader);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_media_cache_reader_get_size(
    xhim_v1_media_cache_reader_t *reader, uint64_t *out_size);

/*
 * Reads at most buffer_size bytes at offset. Short reads are valid; OK with
 * out_bytes_read == 0 means EOF. buffer may be NULL only when buffer_size is
 * zero. offset greater than size is INVALID_ARGUMENT.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_media_cache_reader_read(
    xhim_v1_media_cache_reader_t *reader, uint64_t offset, uint8_t *buffer,
    uint64_t buffer_size, uint64_t *out_bytes_read);

XHIM_V1_API void XHIM_V1_CALL
xhim_v1_media_cache_reader_destroy(xhim_v1_media_cache_reader_t *reader);

/*
 * Edits only a server-confirmed text/plain v1 message. mutation_id is an
 * actor-scoped idempotency key and expected_revision is an exact CAS fence.
 * The server enforces sender ownership and the edit time window.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_edit_text_message(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t conversation_id,
    xhim_v1_bytes_view_t server_message_id,
    xhim_v1_bytes_view_t mutation_id, uint64_t expected_revision,
    xhim_v1_bytes_view_t text,
    xhim_v1_message_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

/*
 * Recalls a server-confirmed message while preserving its identity/order as a
 * permanent tombstone. The service enforces sender time windows and group
 * owner/admin moderation permissions.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_recall_message(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t conversation_id,
    xhim_v1_bytes_view_t server_message_id,
    xhim_v1_bytes_view_t mutation_id, uint64_t expected_revision,
    xhim_v1_message_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

/*
 * Reads one message from the current canonical account by client_message_id.
 * The query is serialized on the Client Actor and fenced by account Epoch.
 *
 * Success completes with XHIM_V1_STATUS_OK and a non-null snapshot. An
 * unknown ID completes with XHIM_V1_STATUS_NOT_FOUND and a null snapshot.
 * This online query requires an active Ready session. Use the independent
 * OfflineReader APIs for read-only access without a live Client; online
 * timeline and conversation pagination are exposed by their list APIs.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_get_message(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t client_message_id,
    xhim_v1_message_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

/*
 * Explicitly retries a permanently failed local message. The Message and
 * Outbox rows transition atomically. Repeating the operation after it has
 * already returned to Pending succeeds without applying another transition.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_retry_message(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t client_message_id,
    xhim_v1_message_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

/*
 * Cancels Pending/Retrying/Failed local work before a transport lease is
 * acquired. Sending or server-accepted messages complete with INVALID_STATE;
 * repeated cancellation is an idempotent success.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_cancel_message(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t client_message_id,
    xhim_v1_message_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

/*
 * Reads a conversation page in newest-first authoritative display order.
 * An empty cursor starts from the newest message. limit=0 selects
 * XHIM_V1_DEFAULT_MESSAGE_PAGE_SIZE; larger values are rejected above
 * XHIM_V1_MAX_MESSAGE_PAGE_SIZE.
 *
 * A cursor belongs to the account and conversation that produced it. It is
 * intentionally opaque and may contain NUL bytes. This client API requires
 * Ready; pre-login and extension reads use xhim_v1_offline_reader_* instead.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_list_messages(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t conversation_id,
    xhim_v1_bytes_view_t cursor, uint32_t limit,
    xhim_v1_message_page_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

/*
 * Searches fallback_text in the current account's local message projection.
 * Results use the same newest-first page and opaque cursor contract as
 * xhim_v1_client_list_messages. This performs no network request.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_search_messages(
    xhim_v1_client_t *client,
    const xhim_v1_message_search_query_t *query,
    xhim_v1_bytes_view_t cursor, uint32_t limit,
    xhim_v1_message_page_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

/*
 * Reads the current account's conversation index. Pinned conversations are
 * first, followed by descending durable activity order. An empty cursor starts
 * at the top. limit=0 selects XHIM_V1_DEFAULT_CONVERSATION_PAGE_SIZE.
 *
 * The cursor is opaque binary data and is scoped to the authenticated account.
 * This first slice requires Ready, matching the message query APIs.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_list_conversations(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t cursor, uint32_t limit,
    xhim_v1_conversation_page_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

/*
 * Advances the current user's read watermark to read_server_sequence. The
 * value must identify a locally known server-confirmed message. Core waits for
 * the service response before mutating SQLite; same/lower watermarks are
 * idempotent and do not publish another changed event.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_mark_conversation_read(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t conversation_id,
    int64_t read_server_sequence,
    xhim_v1_conversation_read_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_client_mark_all_conversations_read(
    xhim_v1_client_t *client,
    const xhim_v1_mark_all_conversations_read_input_t *input,
    xhim_v1_mark_all_conversations_read_completion_callback callback,
    void *user_data, uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_get_total_unread_count(
    xhim_v1_client_t *client,
    xhim_v1_total_unread_count_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_client_list_conversation_peer_reads(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t conversation_id,
    uint32_t limit,
    xhim_v1_conversation_peer_read_page_completion_callback callback,
    void *user_data, uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_set_conversation_preference(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t conversation_id,
    const xhim_v1_conversation_preference_input_t *preference,
    xhim_v1_conversation_preference_completion_callback callback,
    void *user_data, uint64_t *out_request_id);

/*
 * Draft bytes remain local to the encrypted account database. Set/get/clear
 * are asynchronous so hosts never perform SQLite I/O on the UI thread.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_set_conversation_draft(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t conversation_id,
    const xhim_v1_message_input_t *draft,
    xhim_v1_conversation_draft_completion_callback callback, void *user_data,
    uint64_t *out_request_id);
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_get_conversation_draft(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t conversation_id,
    xhim_v1_conversation_draft_completion_callback callback, void *user_data,
    uint64_t *out_request_id);
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_clear_conversation_draft(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t conversation_id,
    xhim_v1_conversation_draft_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_list_friend_requests(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t cursor, uint32_t limit,
    xhim_v1_social_page_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_list_friendships(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t cursor, uint32_t limit,
    xhim_v1_social_page_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_list_groups(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t cursor, uint32_t limit,
    xhim_v1_social_page_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_list_group_members(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t conversation_id,
    xhim_v1_bytes_view_t cursor, uint32_t limit,
    xhim_v1_social_page_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_list_blocks(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t cursor, uint32_t limit,
    xhim_v1_social_page_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_list_group_join_requests(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t cursor, uint32_t limit,
    xhim_v1_social_page_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

/*
 * Authenticated product APIs. Deployment endpoints, bearer credentials,
 * operation IDs, and wire formats remain owned by Core/Product Adapter.
 */
XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_client_get_current_user_profile(
    xhim_v1_client_t *client,
    xhim_v1_user_profile_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_get_user_profiles(
    xhim_v1_client_t *client, const xhim_v1_bytes_view_t *user_ids,
    uint32_t user_id_count,
    xhim_v1_user_profile_page_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_client_update_current_user_profile(
    xhim_v1_client_t *client,
    const xhim_v1_profile_update_input_t *update,
    xhim_v1_user_profile_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_client_get_or_create_direct_conversation(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t peer_user_id,
    xhim_v1_direct_conversation_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_register_push_device(
    xhim_v1_client_t *client, const xhim_v1_push_device_input_t *device,
    xhim_v1_push_device_registration_completion_callback callback,
    void *user_data, uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_disable_push_device(
    xhim_v1_client_t *client, xhim_v1_bytes_view_t device_id,
    xhim_v1_push_device_disable_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_send_friend_request(
    xhim_v1_client_t *client,
    const xhim_v1_send_friend_request_input_t *input,
    xhim_v1_friend_request_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_resolve_friend_request(
    xhim_v1_client_t *client,
    const xhim_v1_resolve_friend_request_input_t *input,
    xhim_v1_friend_request_resolution_completion_callback callback,
    void *user_data, uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_delete_friendship(
    xhim_v1_client_t *client,
    const xhim_v1_delete_friendship_input_t *input,
    xhim_v1_friendship_deletion_completion_callback callback,
    void *user_data, uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_set_friend_remark(
    xhim_v1_client_t *client,
    const xhim_v1_set_friend_remark_input_t *input,
    xhim_v1_friendship_remark_completion_callback callback,
    void *user_data, uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_publish_presence(
    xhim_v1_client_t *client,
    const xhim_v1_publish_presence_input_t *input,
    xhim_v1_presence_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_publish_typing(
    xhim_v1_client_t *client,
    const xhim_v1_publish_typing_input_t *input,
    xhim_v1_typing_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_create_group(
    xhim_v1_client_t *client, const xhim_v1_create_group_input_t *input,
    xhim_v1_group_change_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_change_group_members(
    xhim_v1_client_t *client,
    const xhim_v1_change_group_members_input_t *input,
    xhim_v1_group_change_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_leave_group(
    xhim_v1_client_t *client, const xhim_v1_leave_group_input_t *input,
    xhim_v1_group_lifecycle_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_dismiss_group(
    xhim_v1_client_t *client, const xhim_v1_dismiss_group_input_t *input,
    xhim_v1_group_lifecycle_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_set_block(
    xhim_v1_client_t *client, const xhim_v1_set_block_input_t *input,
    xhim_v1_block_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_request_group_join(
    xhim_v1_client_t *client,
    const xhim_v1_request_group_join_input_t *input,
    xhim_v1_group_join_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_resolve_group_join(
    xhim_v1_client_t *client,
    const xhim_v1_resolve_group_join_input_t *input,
    xhim_v1_group_join_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_change_group_governance(
    xhim_v1_client_t *client,
    const xhim_v1_change_group_governance_input_t *input,
    xhim_v1_group_change_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_get_message_history(
    xhim_v1_client_t *client,
    const xhim_v1_message_history_query_t *query,
    xhim_v1_message_history_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_delete_message_for_self(
    xhim_v1_client_t *client,
    const xhim_v1_delete_message_for_self_input_t *input,
    xhim_v1_message_visibility_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_clear_conversation(
    xhim_v1_client_t *client,
    const xhim_v1_clear_conversation_input_t *input,
    xhim_v1_conversation_view_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_hide_conversation(
    xhim_v1_client_t *client,
    const xhim_v1_hide_conversation_input_t *input,
    xhim_v1_conversation_view_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_list_device_sessions(
    xhim_v1_client_t *client,
    xhim_v1_device_session_page_completion_callback callback, void *user_data,
    uint64_t *out_request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_revoke_device_session(
    xhim_v1_client_t *client,
    const xhim_v1_revoke_device_session_input_t *input,
    xhim_v1_device_session_revocation_completion_callback callback,
    void *user_data, uint64_t *out_request_id);

/*
 * Cooperatively cancels a pending asynchronous request and resolves that
 * request's original callback exactly once with XHIM_V1_STATUS_CANCELLED.
 * Cancellation prevents a later result callback but does not roll back a
 * transaction or lifecycle transition that already committed. NOT_FOUND means
 * the request ID was never issued by this client (or was already pruned);
 * INVALID_STATE means completion won the race.
 */
XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_cancel_request(
    xhim_v1_client_t *client, uint64_t request_id);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_subscribe(
    xhim_v1_client_t *client, xhim_v1_event_callback callback, void *user_data,
    xhim_v1_subscription_t **out_subscription);

XHIM_V1_API void XHIM_V1_CALL
xhim_v1_subscription_cancel(xhim_v1_subscription_t *subscription);

XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_client_get_state(xhim_v1_client_t *client, int32_t *out_state);

/*
 * Returns a synchronous in-memory snapshot and performs no disk/network I/O
 * and invokes no callback. The caller owns out_snapshot and may call this from
 * any thread while the client handle is alive. Before the call, initialize
 * out_snapshot->struct_size to the allocated byte capacity. Core writes only
 * the known prefix that fits that capacity and preserves the capacity value;
 * undersized buffers return XHIM_V1_STATUS_INVALID_ARGUMENT.
 * Compatibility and device-policy outputs also require abi_version to equal
 * XHIM_V1_ABI_VERSION and return INVALID_STATE until an authenticated snapshot
 * is active. Their inline strings remain owned by the caller.
 */
XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_client_get_compatibility(
    xhim_v1_client_t *client,
    xhim_v1_compatibility_snapshot_t *out_snapshot);

XHIM_V1_API int32_t XHIM_V1_CALL
xhim_v1_client_get_device_session_policy(
    xhim_v1_client_t *client,
    xhim_v1_device_session_policy_snapshot_t *out_snapshot);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_get_diagnostics(
    xhim_v1_client_t *client,
    xhim_v1_diagnostics_snapshot_t *out_snapshot);

XHIM_V1_API int32_t XHIM_V1_CALL xhim_v1_client_shutdown(
    xhim_v1_client_t *client, xhim_v1_completion_callback callback,
    void *user_data, uint64_t *out_request_id);

/*
 * Handle and destruction contract:
 *
 * - Client APIs may be called concurrently while the client is alive.
 * - client_destroy must be externally serialized against all client API calls;
 *   after it begins, no thread may start another call with that handle.
 * - subscription_cancel must not be called concurrently or more than once for
 *   the same subscription handle.
 * - client_destroy stops callback admission, discards queued callbacks, waits
 *   for a callback already running, and performs final Core shutdown.
 * - Calling client_destroy from that client's callback is supported. The
 *   current callback is allowed to finish, but no later callback will start.
 * - Subscription handles should be cancelled before client_destroy. A handle
 *   not yet cancelled may only be passed once to subscription_cancel; it
 *   cannot be used for any other operation after client destruction.
 */
XHIM_V1_API void XHIM_V1_CALL xhim_v1_client_destroy(xhim_v1_client_t *client);

#ifdef __cplusplus
} // extern "C"
#endif

#endif // XHIM_XHIM_V1_H_
