declare module 'rclnodejs' {
  /**
   * A callback for receiving published messages.
   * If the callback accepts two parameters, the second will be a MessageInfo
   * containing metadata about the received message.
   *
   * @param message - The published message.
   * @param messageInfo - Optional metadata about the message (timestamps, publisher GID, etc).
   *
   * @remarks
   * See {@link Node#createSubscription | Node.createSubscription}
   * See {@link SubscriptionContentFilter}
   * See {@link Node#createPublisher | Node.createPublisher}
   * See {@link Publisher}
   * See {@link Subscription}
   */
  type SubscriptionCallback<T extends TypeClass<MessageTypeClassName>> =
    // * @param message - The published message
    (message: MessageType<T>, messageInfo?: MessageInfo) => void;

  /**
   * A callback for receiving published raw messages.
   * If the callback accepts a second parameter, it will receive a MessageInfo
   * containing metadata about the received message.
   *
   * @param message - The published message.
   * @param messageInfo - Optional metadata about the message.
   *
   * @remarks
   * See {@link Node#createSubscription | Node.createSubscription}
   * See {@link SubscriptionContentFilter}
   * See {@link Node#createPublisher | Node.createPublisher}
   * See {@link Publisher}
   * See {@link Subscription}
   */
  type SubscriptionWithRawMessageCallback =
    // * @param message - The published raw message
    (message: Buffer, messageInfo?: MessageInfo) => void;

  /**
   * A ROS Subscription for published messages on a topic.
   */
  interface Subscription extends Entity {
    /**
     * Topic to listen for messages on.
     */
    readonly topic: string;

    /**
     * Specifies if messages are in raw (binary) format
     */
    readonly isRaw: boolean;

    /**
     * Check if content filtering is supported for this subscription.
     * @returns True if the subscription instance supports content filtering; otherwise false.
     */
    isContentFilterSupported(): boolean;

    /**
     * Test if the RMW supports content-filtered topics and that this subscription
     * is configured with a well formed content-filter.
     * @returns {boolean} True if content-filtering will be applied; otherwise false.
     */
    hasContentFilter(): boolean;

    /**
     * Set a content-filter if the RMW supports content-filtered topics.
     * @param contentFilter - The content-filter description to apply.
     * @returns True if successful; false otherwise
     * @remarks
     * @see {@link https://www.omg.org/spec/DDS/1.4/PDF|DDS 1.4 specification, Annex B}
     */
    setContentFilter(filter: SubscriptionContentFilter): boolean;

    /**
     * Get the current content-filter.
     * @returns The content-filter description {expression: string, parameters: string[]} or undefined if not set/supported.
     */
    getContentFilter(): SubscriptionContentFilter | undefined;

    /**
     * Clear the current content-filter. No filtering is to be applied.
     * @returns True if successful; false otherwise
     */
    clearContentFilter(): boolean;

    /**
     * Get the number of publishers to this subscription.
     * @returns The number of publishers
     */
    publisherCount(): number;

    /**
     * Get the logger name for this subscription.
     */
    readonly loggerName: string;
  }
}
