/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Behavior } from "#behavior/Behavior.js";
import { ClusterBehavior } from "#behavior/cluster/ClusterBehavior.js";
import type { GlobalAttributeState } from "#behavior/cluster/ClusterState.js";
import { ActionContext } from "#behavior/context/ActionContext.js";
import { Construction, Diagnostic, Environment, Immutable, Lifetime, MaybePromise, Observable } from "@matter/general";
import { DataModelPath } from "@matter/model";
import { Val } from "@matter/protocol";
import { EndpointNumber } from "@matter/types";
import { Agent } from "./Agent.js";
import { Behaviors } from "./properties/Behaviors.js";
import { Commands } from "./properties/Commands.js";
import { EndpointContainer } from "./properties/EndpointContainer.js";
import { EndpointLifecycle } from "./properties/EndpointLifecycle.js";
import { Parts } from "./properties/Parts.js";
import { SupportedBehaviors } from "./properties/SupportedBehaviors.js";
import { EndpointType } from "./type/EndpointType.js";
/**
 * Endpoints consist of a hierarchy of parts.  This class manages the current state of a single endpoint.
 *
 * You can interact with endpoints using an {@link Agent} created with {@link Endpoint.agentFor}.  Agents are stateless and
 * designed for quick instantiation so you can create them as needed then discard.
 *
 * Most often direct access to {@link Agent} is transparent as Matter.js acquires an agent as necessary for
 * {@link Behavior} interactions.
 */
export declare class Endpoint<T extends EndpointType = EndpointType.Empty> {
    #private;
    [Diagnostic.value]: unknown;
    /**
     * A string that uniquely identifies an endpoint.
     *
     * This ID must be unique amongst all Parts with the same owner.
     */
    get id(): string;
    /**
     * The endpoint ID or undefined if not yet assigned.
     */
    get maybeId(): string | undefined;
    /**
     * The Matter {@link EndpointNumber} of the endpoint.  This uniquely identifies the {@link Endpoint} in the scope of the
     * Matter node.
     */
    get number(): EndpointNumber;
    /**
     * The endpoint number or undefined if not yet assigned.
     */
    get maybeNumber(): EndpointNumber | undefined;
    /**
     * The owner of the endpoint.
     *
     * Every endpoint but the root endpoint (the "server node") is owned by another endpoint.
     */
    get owner(): Endpoint | undefined;
    /**
     * Access an {@link Agent} for this endpoint.
     *
     * An {@link Agent} allows you to interact directly with the behaviors supported by the endpoint.  Normally you
     * would use {@link act} to obtain an agent but {@link agentFor} is useful if you need to interact with multiple
     * endpoints in the same context.
     */
    agentFor<T extends EndpointType>(this: Endpoint<T>, context: ActionContext): Agent.Instance<T>;
    get endpointProtocol(): import("@matter/protocol").EndpointProtocol | undefined;
    /**
     * Search for the owner of a specific type.
     *
     * Returns undefined if this owner is not found on the way up to the root endpoint.
     */
    ownerOfType<T extends EndpointType.Empty>(type: T): Endpoint<T> | undefined;
    /**
     * The endpoint's environment.  Endpoint implementations use the environment to access platform components such as
     * storage and network components.
     */
    get env(): Environment;
    /**
     * Access the pool of behaviors supported by this endpoint.
     */
    get behaviors(): Behaviors;
    /**
     * Current state values for all behaviors, keyed by behavior ID.  This view is read-only.
     */
    get state(): Immutable<SupportedBehaviors.StateOf<T["behaviors"]>>;
    /**
     * Current state for a specific behavior ID.
     *
     * Be aware that using a string type does not provide type checking and does not enforce the correctness of the used
     * Behavior type including all enabled features. Because of this the returned state is typed as a plain string
     * indexed record (Val.Struct). Please ensure to have proper checks in place when using this method with string type.
     */
    stateOf(type: string): Immutable<Val.Struct>;
    /**
     * Current state for a specific behavior.
     *
     * This is the recommended way to access state for a specific behavior because it provides proper type checking
     * and enforces the correctness of the used Behavior type including all enabled features.
     */
    stateOf<T extends Behavior.Type>(type: T): Immutable<Behavior.StateOf<T>>;
    /**
     * Version of {@link stateOf} that returns undefined instead of throwing if the requested behavior unsupported.
     */
    maybeStateOf(type: string): Immutable<Val.Struct> | undefined;
    /**
     * Version of {@link stateOf} that returns undefined instead of throwing if the requested behavior unsupported.
     */
    maybeStateOf<T extends Behavior.Type>(type: T): Immutable<Behavior.StateOf<T>> | undefined;
    /**
     * Update state values.  This is a patch operation; it only modifies properties in {@link values}.
     *
     * {@link values} is an object with a {@link Behavior.id} as the key and state values as sub-objects.
     *
     * Input values must adhere to the {@link Behavior.schema} of the target {@link Behavior}.  If not, set will throw
     * an error.
     *
     * This is a transactional operation.  An error results in no change.  The endpoint will wait for exclusive access
     * before applying changes.
     *
     * @param values the values to change
     */
    set(values: SupportedBehaviors.StatePatchOf<T["behaviors"]>): Promise<void>;
    /**
     * Update state values for a single behavior.
     *
     * The patch semantics used here are identical to {@link set}.
     *
     * This is the recommended way to set state for a single behavior because it provides proper type checking and
     * enforces the correctness of the used Behavior type including all enabled features.
     *
     * @param type the {@link Behavior} to patch
     * @param values the values to change
     */
    setStateOf<T extends Behavior.Type>(type: T, values: Behavior.PatchStateOf<T>): Promise<void>;
    /**
     * Update state values for a single behavior ID.
     *
     * The patch semantics used here are identical to {@link set}.
     *
     * Be aware that using a string type does not provide type checking and does not enforce the correctness of the used
     * Behavior type including all enabled features. Expect runtime errors if the provided values are not compatible
     * with the actual Behavior type.
     *
     * @param type the {@link Behavior} to patch
     * @param values the values to change
     */
    setStateOf(type: string, values: Val.Struct): Promise<void>;
    /**
     * Typed read of a single behavior's state.
     *
     * Same client/server semantics as {@link get}, including the partial-state-on-failure contract.
     *
     * When a key-list selector is provided, each returned value may be `undefined` — absent on unsupported
     * attributes or those excluded by {@link EndpointReadFailedError}.
     */
    getStateOf<B extends Behavior.Type>(type: B, selector?: true, options?: Endpoint.GetOptions): Promise<Behavior.StateOf<B>>;
    getStateOf<B extends Behavior.Type, K extends keyof Behavior.StateOf<B>>(type: B, selector: readonly K[], options?: Endpoint.GetOptions): Promise<{
        readonly [P in K]?: Behavior.StateOf<B>[P];
    }>;
    /**
     * Read of a single behavior's state by string id.
     *
     * @throws {@link EndpointBehaviorNotPresentError} if `type` is not present on the endpoint.
     */
    getStateOf(type: string, selector?: readonly string[], options?: Endpoint.GetOptions): Promise<Val.Struct>;
    /**
     * Reads the selected behavior state.
     *
     * @remarks
     * **Client endpoint.** Issues a single batched Matter Read for the selected attribute paths
     * and returns the fresh slice. State is updated as data arrives; reads whose fabric-filter
     * setting differs from the active subscription are not cached.
     *
     * **Partial-state contract on failure.** On any per-path failure status, rejects with
     * {@link EndpointReadFailedError}. The error carries both the failed paths and the assembled
     * partial slice for successful paths.
     *
     * **Server endpoint.** Returns a snapshot of local immutable state. `fabricFilter` is ignored.
     */
    get(): Promise<Immutable<SupportedBehaviors.StateOf<T["behaviors"]>>>;
    get(selector: undefined, options?: Endpoint.GetOptions): Promise<Immutable<SupportedBehaviors.StateOf<T["behaviors"]>>>;
    get<S extends StateSelector<T>>(selector: S, options?: Endpoint.GetOptions): Promise<StateSliceOf<T, S>>;
    /**
     * Commands for all behaviors keyed by behavior ID.
     */
    get commands(): Commands<T>;
    /**
     * Commands for a specific behavior id. Untyped: each command is `Commands.Command`.
     *
     * @throws {@link EndpointBehaviorNotPresentError} if `type` is not present on the endpoint.
     */
    commandsOf(type: string): Record<string, Commands.Command>;
    /** Typed variant of {@link commandsOf}; preserves the behavior's command interface. */
    commandsOf<T extends Behavior.Type>(type: T): Commands.OfBehavior<T>;
    /**
     * Events for all behaviors keyed by behavior ID.
     */
    get events(): SupportedBehaviors.EventsOf<T["behaviors"]>;
    /**
     * Events for a specific behavior ID.
     *
     * Be aware that using a string type does not provide type checking and does not enforce the correctness of the used
     * Behavior type including all enabled features. Because of this each event is typed as Observable | undefined.
     * Please ensure to have proper checks in place when using this method with string type.
     */
    eventsOf(type: string): Immutable<Record<string, Observable | undefined>>;
    /**
     * Events for a specific behavior.
     *
     * This is the recommended way to access events for a specific behavior because it provides proper type checking
     * and enforces the correctness of the used Behavior type including all enabled features.
     */
    eventsOf<T extends Behavior.Type>(type: T): Behavior.EventsOf<T>;
    /**
     * Activated cluster features for a behavior id, keyed by the camelCased feature title - same shape as the
     * static `features` map on cluster behavior types and as `this.features` inside a server cluster instance.
     *
     * @throws {@link EndpointBehaviorNotPresentError} if `type` is not present on the endpoint.
     * @throws {@link EndpointBehaviorNotClusterError} if `type` is present but is not a cluster behavior.
     */
    featuresOf(type: string): Immutable<Record<string, boolean>>;
    /** Typed variant of {@link featuresOf}; preserves the cluster's feature flag type from {@link ClusterBehavior.Type}. */
    featuresOf<T extends ClusterBehavior.Type>(type: T): T["features"];
    /** Returns undefined if `type` is unknown or not a cluster behavior; otherwise behaves like {@link featuresOf}. */
    maybeFeaturesOf(type: string): Immutable<Record<string, boolean>> | undefined;
    maybeFeaturesOf<T extends ClusterBehavior.Type>(type: T): T["features"] | undefined;
    /**
     * Global attribute state (clusterRevision, featureMap, attributeList, acceptedCommandList, generatedCommandList)
     * for a behavior id. These attributes are managed automatically and omitted from the default {@link stateOf}
     * shape to reduce noise; this accessor exposes them when needed.
     *
     * For server clusters values are populated at construction. For client clusters values come from remote
     * subscription / read responses and may be empty arrays before the first read completes.
     *
     * @throws {@link EndpointBehaviorNotPresentError} if `type` is not present on the endpoint.
     * @throws {@link EndpointBehaviorNotClusterError} if `type` is present but is not a cluster behavior.
     */
    globalsOf(type: string): Immutable<GlobalAttributeState>;
    /** Typed variant of {@link globalsOf}; narrows `featureMap` to the cluster's per-feature flag type. */
    globalsOf<T extends ClusterBehavior.Type>(type: T): Immutable<Omit<GlobalAttributeState, "featureMap"> & {
        featureMap: T["features"];
    }>;
    /** Returns undefined if `type` is unknown or not a cluster behavior; otherwise behaves like {@link globalsOf}. */
    maybeGlobalsOf(type: string): Immutable<GlobalAttributeState> | undefined;
    maybeGlobalsOf<T extends ClusterBehavior.Type>(type: T): Immutable<Omit<GlobalAttributeState, "featureMap"> & {
        featureMap: T["features"];
    }> | undefined;
    get construction(): Construction<Endpoint<T>>;
    /**
     * Create new endpoint.
     *
     * The endpoint will not initialize fully until added to a {@link Node}.  You can use {@link Endpoint.add} to
     * construct and initialize an {@link Endpoint} in one step.
     */
    constructor(config: Endpoint.Configuration<T> | T);
    /**
     * Create new endpoint.
     *
     * The endpoint will not initialize fully until added to a {@link Node}.  You can use {@link Endpoint.add} to
     * construct and initialize an {@link Endpoint} in one step.
     */
    constructor(type: T, options?: Endpoint.Options<T>);
    set id(id: string);
    protected get container(): undefined | EndpointContainer;
    set number(number: number);
    set owner(owner: Endpoint | undefined);
    /**
     * Add a child endpoint.  If this endpoint is initialized, awaits child initialization.
     *
     * If child initialization fails:
     *
     *   - If the child is essential (@see {@link EndpointLifecycle#isEssential}), removes the child and rethrows
     *
     *   - If the child is non-essential then logs the error but leaves the child installed.
     *
     * @param endpoint the {@link Endpoint} or {@link Endpoint.Configuration}
     */
    add<T extends EndpointType>(endpoint: Endpoint<T> | Endpoint.Configuration<T> | T): Promise<Endpoint<T>>;
    /**
     * Add a child endpoint with separate type and options arguments.
     *
     * @param type the {@link EndpointType} of the child endpoint
     * @param options settings for the new endpoint
     */
    add<T extends EndpointType>(type: T, options?: Endpoint.Options<T>): Promise<Endpoint<T>>;
    /**
     * The type of endpoint this endpoint implements.
     */
    get type(): EndpointType;
    /**
     * Access child parts.
     */
    get parts(): Parts;
    /**
     * Is this a parent Endpoint?
     */
    get hasParts(): boolean;
    /**
     * Endpoint information that varies as the endpoint initializes.
     */
    get lifecycle(): EndpointLifecycle;
    protected createLifecycle(isEssential?: boolean): EndpointLifecycle;
    /**
     * Create an {@link Agent.Type} for the endpoint.
     */
    get agentType(): Agent.Type<T>;
    /**
     * Execute a function against an {@link Agent} for the endpoint.
     *
     * Agents provide the highest-leve API for interacting with endpoints.  The agent is a composite object with
     * properties for each supported behavior.
     *
     * State changes made by {@link actor} are atomic and made permanent only when the actor exits unless you commit the
     * transaction manually.
     *
     * {@link actor} runs in an "offline" context where ACLs are ignored and all state is read/write.
     *
     * The {@link Agent} is destroyed after {@link actor} exits so you should not maintain references to the agent, its
     * behaviors or associated state.
     *
     * {@link actor} may be async.  If so, the acting context will remain open until the returned {@link Promise}
     * resolves.
     *
     * @param purpose textual description of operation used for diagnostics
     * @param actor the function that performs the action
     */
    act<R>(purpose: string, actor: (agent: Agent.Instance<T>) => MaybePromise<R>): MaybePromise<R>;
    /**
     * Version of {@link act} without explicit diagnostic purpose.
     */
    act<R>(actor: (agent: Agent.Instance<T>) => MaybePromise<R>): MaybePromise<R>;
    /**
     * Perform "soft" reset of the endpoint, reverting all in-memory structures to uninitialized.
     */
    reset(): Promise<void>;
    /**
     * Perform "hard" reset of the endpoint, reverting all in-memory and persistent state to uninitialized.
     */
    erase(): Promise<void>;
    /**
     * Erase all persisted data and destroy the endpoint.
     */
    delete(): Promise<void>;
    /**
     * Apply a depth-first visitor function to myself and all descendents.
     */
    visit<T extends void | PromiseLike<void>>(visitor: (endpoint: Endpoint) => T): T;
    close(): Promise<void>;
    [Construction.destruct](): Promise<void>;
    [Symbol.asyncDispose](): Promise<void>;
    toString(): string;
    /**
     * Path identifying the endpoint in the Matter data model.
     */
    get path(): DataModelPath;
    /**
     * Diagnostic identity.
     *
     * This is an unqualified path segment.
     */
    get identity(): string | EndpointNumber;
    /**
     * Asynchronous initialization.
     *
     * Derivatives may override to perform async construction prior to full initialization.
     */
    protected initialize(): MaybePromise;
    /**
     * Ensure requirements for construction are met.
     */
    protected assertConstructable(): void;
    /**
     * Complete initialization.  Invoked via {@link Construction#start} by the owner.
     */
    [Construction.construct](): MaybePromise;
    get [Lifetime.owner](): Lifetime.Owner | undefined;
    /**
     * Diagnostic information regarding endpoint state.
     */
    get diagnosticDict(): Record<string, unknown>;
}
export declare namespace Endpoint {
    type BehaviorOptions<T extends EndpointType = EndpointType.Empty, O extends EndpointOptions = EndpointOptions> = {
        -readonly [K in keyof T["behaviors"] as K extends keyof O ? never : K]?: Behavior.Options<T["behaviors"][K]>;
    };
    interface EndpointOptions {
        /**
         * The owner of the endpoint.
         *
         * If provided, takes ownership of the endpoint at construction.
         */
        owner?: Endpoint | Agent;
        /**
         * The endpoint's string identifier.  Must be unique within the parent.
         *
         * If you omit the identifier the node assigns a generated one for you.
         */
        id?: string;
        /**
         * The endpoint number.  Must be unique within the node.
         *
         * If you omit the endpoint number the node assigns a sequential one for you.
         */
        number?: number;
        /**
         * Child endpoints.
         *
         * This is the inverse of setting {@link owner} above.  The endpoint instantiates and takes ownership of child
         * endpoints at construction time.
         */
        parts?: Iterable<Endpoint.Definition>;
        /**
         * Designates whether an endpoint is essential.
         *
         * Endpoints are essential by default but you may disable by setting this to false.
         */
        isEssential?: boolean;
    }
    type Options<T extends EndpointType = EndpointType.Empty, O extends EndpointOptions = EndpointOptions> = BehaviorOptions<T, O> & O;
    type Configuration<T extends EndpointType = EndpointType.Empty, O extends EndpointOptions = EndpointOptions> = Options<T, O & {
        type: T;
    }> & {
        type: T;
    };
    /**
     * Definition of an endpoint.  May be an {@link EndpointType}, {@link Configuration}, or a {@link Endpoint}
     * instance.
     */
    type Definition<T extends EndpointType = EndpointType.Empty> = T | Configuration<T> | Endpoint<T>;
    /**
     * Options for {@link Endpoint.get} and {@link Endpoint.getStateOf}.
     */
    interface GetOptions {
        /**
         * When `false`, the underlying Matter Read is not fabric-filtered. Defaults to `true`.
         */
        fabricFilter?: boolean;
        /**
         * When `true`, skips automatic data-version filter injection so the server returns all attribute values
         * regardless of whether they have changed since the last read or subscription. Defaults to `false`.
         */
        includeKnownVersions?: boolean;
    }
    /**
     * Obtain a configuration from constructor parameters.
     */
    function configurationFor<T extends EndpointType>(definition: T | Endpoint.Configuration<T>, options?: Endpoint.Options<T>): Configuration<T, EndpointOptions>;
    /**
     * Obtain an endpoint for the given {@link Definition}.
     */
    function partFor<T extends EndpointType>(definition: Definition<T>): Endpoint<T>;
}
export type BehaviorOf<T extends EndpointType> = T["behaviors"][keyof T["behaviors"]];
export type BehaviorAt<T extends EndpointType, K extends keyof T["behaviors"]> = T["behaviors"][K];
export type BehaviorSelection<B extends Behavior.Type> = true | readonly (keyof Behavior.StateOf<B>)[];
export type RawBehaviorSelection = true | readonly string[];
export type StateSelector<T extends EndpointType> = {
    [K in keyof T["behaviors"]]?: string extends K ? RawBehaviorSelection : T["behaviors"][K] extends Behavior.Type ? BehaviorSelection<T["behaviors"][K]> : RawBehaviorSelection;
};
export type StateSliceOf<T extends EndpointType, S> = S extends undefined ? Immutable<SupportedBehaviors.StateOf<T["behaviors"]>> : {
    [K in keyof S & keyof T["behaviors"]]: S[K] extends true ? Immutable<Behavior.StateOf<BehaviorAt<T, K>>> : S[K] extends readonly (infer A)[] ? Immutable<Partial<Pick<Behavior.StateOf<BehaviorAt<T, K>>, Extract<A, keyof Behavior.StateOf<BehaviorAt<T, K>>>>>> : never;
};
//# sourceMappingURL=Endpoint.d.ts.map