import type { GetDeviceConfig } from "@zwave-js/config";
import { type GetNode, type GetSupportedCCVersion, type HostIDs, type MaybeNotKnown, type MessageOrCCLogEntry, type MessagePriority, type NodeIDType, type NodeId, type SecurityClass, type SecurityManagers, type SupportsCC } from "@zwave-js/core";
import { Bytes, type BytesView, type JSONObject, type TypedClassDecorator } from "@zwave-js/shared";
import { FunctionType, MessageType } from "./Constants.js";
export type MessageConstructor<T extends Message> = typeof Message & {
    new (options: MessageBaseOptions): T;
};
/** Where a serialized message originates from, to distinguish how certain messages need to be deserialized */
export declare enum MessageOrigin {
    Controller = 0,
    Host = 1
}
export interface MessageParsingContext extends HostIDs, GetDeviceConfig {
    /** How many bytes a node ID occupies in serial API commands */
    nodeIdType: NodeIDType;
    sdkVersion: string | undefined;
    requestStorage: Map<FunctionType, Record<string, unknown>> | undefined;
    origin?: MessageOrigin;
}
export interface MessageBaseOptions {
    callbackId?: number;
}
export interface MessageOptions extends MessageBaseOptions {
    type?: MessageType;
    functionType?: FunctionType;
    expectedResponse?: FunctionType | typeof Message | ResponsePredicate;
    expectedCallback?: FunctionType | typeof Message | ResponsePredicate;
    payload?: Bytes;
}
export interface MessageEncodingContext extends Readonly<SecurityManagers>, HostIDs, GetSupportedCCVersion, GetDeviceConfig {
    /** How many bytes a node ID occupies in serial API commands */
    nodeIdType: NodeIDType;
    getHighestSecurityClass(nodeId: number): MaybeNotKnown<SecurityClass>;
    hasSecurityClass(nodeId: number, securityClass: SecurityClass): MaybeNotKnown<boolean>;
    setSecurityClass(nodeId: number, securityClass: SecurityClass, granted: boolean): void;
}
export interface HasNodeId {
    nodeId: number;
}
/** Tests if the given message is for a node or references a node */
export declare function hasNodeId<T extends Message>(msg: T): msg is T & HasNodeId;
export declare class MessageRaw {
    readonly type: MessageType;
    readonly functionType: FunctionType;
    readonly payload: Bytes;
    constructor(type: MessageType, functionType: FunctionType, payload: Bytes);
    static parse(data: BytesView): MessageRaw;
    withPayload(payload: Bytes): MessageRaw;
}
/**
 * Represents a Z-Wave message for communication with the serial interface
 */
export declare class Message {
    constructor(options?: MessageOptions);
    static parse(data: BytesView, ctx: MessageParsingContext): Message;
    /** Creates an instance of the message that is serialized in the given buffer */
    static from(raw: MessageRaw, ctx: MessageParsingContext): Message;
    type: MessageType;
    functionType: FunctionType;
    expectedResponse: FunctionType | typeof Message | ResponsePredicate | undefined;
    expectedCallback: FunctionType | typeof Message | ResponsePredicate | undefined;
    payload: Bytes;
    /** Used to map requests to callbacks */
    callbackId: number | undefined;
    protected assertCallbackId(): asserts this is this & {
        callbackId: number;
    };
    /** Returns whether the callback ID is set */
    hasCallbackId(): this is this & {
        callbackId: number;
    };
    /**
     * Tests whether this message needs a callback ID to match its response
     */
    needsCallbackId(): boolean;
    /** Returns the response timeout for this message in case the default settings do not apply. */
    getResponseTimeout(): number | undefined;
    /** Returns the callback timeout for this message in case the default settings do not apply. */
    getCallbackTimeout(): number | undefined;
    /**
     * Serializes this message into a Buffer
     */
    serialize(ctx: MessageEncodingContext): Promise<Bytes>;
    /** Generates a representation of this Message for the log */
    toLogEntry(): MessageOrCCLogEntry;
    /** Generates the JSON representation of this Message */
    toJSON(): JSONObject;
    private toJSONInternal;
    private testMessage;
    /** Tests whether this message expects an ACK from the controller */
    expectsAck(): boolean;
    /** Tests whether this message expects a response from the controller */
    expectsResponse(): boolean;
    /** Tests whether this message expects a callback from the controller */
    expectsCallback(): boolean;
    /** Tests whether this message expects an update from the target node to finalize the transaction */
    expectsNodeUpdate(ctx: GetNode<NodeId & SupportsCC>): boolean;
    /** Returns a message specific timeout used to wait for an update from the target node */
    nodeUpdateTimeout: number | undefined;
    /** Checks if a message is an expected response for this message */
    isExpectedResponse(msg: Message): boolean;
    /** Checks if a message is an expected callback for this message */
    isExpectedCallback(msg: Message): boolean;
    /** Checks if a message is an expected node update for this message */
    isExpectedNodeUpdate(ctx: GetNode<NodeId & SupportsCC>, msg: Message): boolean;
    /** Gets set by the driver to remember an expected node update for this message that arrived before the Serial API command has finished. */
    prematureNodeUpdate: Message | undefined;
    /** Finds the ID of the target or source node in a message, if it contains that information */
    getNodeId(): number | undefined;
    /**
     * Returns the node this message is linked to or undefined
     */
    tryGetNode<T extends NodeId>(ctx: GetNode<T>): T | undefined;
    private _transmissionTimestamp;
    /** The timestamp when this message was (last) transmitted (in nanoseconds) */
    get transmissionTimestamp(): number | undefined;
    /** Marks this message as sent and sets the transmission timestamp */
    markAsSent(): void;
    private _completedTimestamp;
    get completedTimestamp(): number | undefined;
    /** Marks this message as completed and sets the corresponding timestamp */
    markAsCompleted(): void;
    /** Returns the round trip time of this message from transmission until completion. */
    get rtt(): number | undefined;
}
export type ResponseRole = "unexpected" | "confirmation" | "final" | "fatal_controller" | "fatal_node";
/**
 * A predicate function to test if a received message matches to the sent message
 */
export type ResponsePredicate<TSent extends Message = Message> = (sentMessage: TSent, receivedMessage: Message) => boolean;
/**
 * Defines the message and function type associated with a Z-Wave message
 */
export declare const messageTypes: <TTarget extends typeof Message>(messageType: MessageType, functionType: FunctionType) => TypedClassDecorator<TTarget>;
/**
 * Retrieves the message type defined for a Z-Wave message class
 */
export declare function getMessageType<T extends Message>(messageClass: T): MessageType | undefined;
/**
 * Retrieves the message type defined for a Z-Wave message class
 */
export declare function getMessageTypeStatic<T extends MessageConstructor<Message>>(classConstructor: T): MessageType | undefined;
/**
 * Retrieves the function type defined for a Z-Wave message class
 */
export declare function getFunctionType<T extends Message>(messageClass: T): FunctionType | undefined;
/**
 * Retrieves the function type defined for a Z-Wave message class
 */
export declare function getFunctionTypeStatic<T extends MessageConstructor<Message>>(classConstructor: T): FunctionType | undefined;
/**
 * Defines the expected response function type or message class for a Z-Wave message
 */
export declare const expectedResponse: <TTarget extends typeof Message>(typeOrPredicate: ResponsePredicate<Message> | typeof Message | FunctionType) => TypedClassDecorator<TTarget>;
/**
 * Retrieves the expected response function type or message class defined for a Z-Wave message class
 */
export declare function getExpectedResponse<T extends Message>(messageClass: T): FunctionType | typeof Message | ResponsePredicate | undefined;
/**
 * Retrieves the function type defined for a Z-Wave message class
 */
export declare function getExpectedResponseStatic<T extends MessageConstructor<Message>>(classConstructor: T): FunctionType | typeof Message | ResponsePredicate | undefined;
/**
 * Defines the expected callback function type or message class for a Z-Wave message
 */
export declare function expectedCallback<TSent extends typeof Message>(typeOrPredicate: FunctionType | typeof Message | ResponsePredicate<InstanceType<TSent>>): TypedClassDecorator<TSent>;
/**
 * Retrieves the expected callback function type or message class defined for a Z-Wave message class
 */
export declare function getExpectedCallback<T extends Message>(messageClass: T): FunctionType | typeof Message | ResponsePredicate | undefined;
/**
 * Retrieves the function type defined for a Z-Wave message class
 */
export declare function getExpectedCallbackStatic<T extends MessageConstructor<Message>>(classConstructor: T): FunctionType | typeof Message | ResponsePredicate | undefined;
/**
 * Defines the default priority associated with a Z-Wave message
 */
export declare const priority: <TTarget extends typeof Message>(prio: MessagePriority) => TypedClassDecorator<TTarget>;
/**
 * Retrieves the default priority defined for a Z-Wave message class
 */
export declare function getDefaultPriority<T extends Message>(messageClass: T): MessagePriority | undefined;
/**
 * Retrieves the default priority defined for a Z-Wave message class
 */
export declare function getDefaultPriorityStatic<T extends MessageConstructor<Message>>(classConstructor: T): MessagePriority | undefined;
//# sourceMappingURL=Message.d.ts.map