/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Events } from "#behavior/Events.js";
import type { Agent } from "#endpoint/Agent.js";
import { MaybePromise } from "@matter/general";
import { type Schema } from "@matter/model";
import { ClusterType, type ClusterTyping } from "@matter/types";
import { Behavior } from "../Behavior.js";
import type { BehaviorBacking } from "../internal/BehaviorBacking.js";
import type { RootSupervisor } from "../supervision/RootSupervisor.js";
import { NetworkBehavior } from "../system/network/NetworkBehavior.js";
import { ExtensionInterfaceOf } from "./cluster-behavior-utils.js";
import type { ClusterEvents } from "./ClusterEvents.js";
import { ClusterInterface } from "./ClusterInterface.js";
import type { ClusterState } from "./ClusterState.js";
/**
 * A {@link Behavior} with specialization for a specific cluster.
 *
 * To implement cluster functionality you should use a subclass provided by {@link ClusterBehavior.for} with the
 * cluster namespace you are implementing.  Most commonly you would use one of the predefined implementations
 * matter.js includes.
 *
 * Subclasses can be modified using the static builder methods or extended like a normal class.
 *
 * Behaviors should store all mutable state in their {@link Behavior.state} property.  Other fields will be transient
 * and may not be retained across invocations.
 *
 * ClusterBehaviors may be instantiated with unsupported mandatory commands and attributes.  This is currently results
 * in a runtime error, but it will not cause a type error during development.
 */
export declare class ClusterBehavior extends Behavior {
    static readonly schema: Schema.Cluster;
    /**
     * The ID of ClusterBehavior implementations is the uncapitalized cluster name.
     */
    static id: Uncapitalize<string>;
    /**
     * The cluster namespace associated with this behavior.
     */
    get cluster(): ClusterType.Concrete;
    /**
     * Supported features as a flag object.
     */
    get features(): Record<string, boolean>;
    get type(): ClusterBehavior.Type;
    /**
     * Every cluster behavior has an associated cluster namespace defined statically.
     */
    static readonly cluster: ClusterType.Concrete;
    /**
     * Supported features as a flag object.
     */
    static readonly features: Record<string, boolean>;
    /**
     * Method definitions.
     */
    static readonly Interface: ClusterTyping;
    /**
     * All ClusterBehavior initialization currently runs as part of {@link Endpoint} initialization.
     */
    static readonly early = true;
    /**
     * Keep networking alive until I'm destroyed.
     */
    static readonly dependencies: (typeof NetworkBehavior)[];
    /**
     * Automatically lock state on command invoke.
     */
    static readonly lockOnInvoke = true;
    constructor(agent: Agent, backing: BehaviorBacking);
    /**
     * Create a new behavior for a specific cluster namespace.
     *
     * If you invoke directly on {@link ClusterBehavior} you will receive a new implementation that reports all commands
     * as unimplemented.
     *
     * If you invoke on an existing subclass, you will receive a new implementation with the cluster in the subclass
     * replaced.  You should generally only do this with a namespace with the same cluster ID.
     */
    static for<This extends ClusterBehavior.Type, const NS extends ClusterType>(this: This, ns: NS, schema?: Schema.Cluster, name?: string): ClusterBehavior.Type<This, NS["Typing"], NS> & {
        readonly id: Uncapitalize<NS["name"] & string>;
    };
    /**
     * Create a new behavior with different cluster features.
     */
    static withFeatures<This extends ClusterBehavior.Type, const FeaturesT extends ClusterType.FeatureSelection<ClusterInterface.InterfaceOf<This>>>(this: This, ...features: FeaturesT): ClusterBehavior.Type<This, ClusterType.WithSupportedFeatures<ClusterInterface.InterfaceOf<This>, ClusterType.FeaturesAsFlags<ClusterInterface.InterfaceOf<This>, FeaturesT>>>;
    /**
     * Alias for {@link withFeatures}.
     */
    static with<This extends ClusterBehavior.Type, const FeaturesT extends ClusterType.FeatureSelection<ClusterInterface.InterfaceOf<This>>>(this: This, ...features: FeaturesT): ClusterBehavior.Type<This, ClusterType.WithSupportedFeatures<ClusterInterface.InterfaceOf<This>, ClusterType.FeaturesAsFlags<ClusterInterface.InterfaceOf<This>, FeaturesT>>, ClusterType.Concrete, This["Internal"], This extends {
        readonly id: infer S extends Uncapitalize<string>;
    } ? S : Uncapitalize<string>>;
    /**
     * Create a new behavior with modified cluster elements.
     */
    static alter<This extends ClusterBehavior.Type, const AlterationsT extends ClusterType.Alterations<ClusterInterface.InterfaceOf<This>>>(this: This, alterations: AlterationsT): ClusterBehavior.Type<This, ClusterType.WithEnabledAttributes<ClusterType.WithEnabledEvents<ClusterInterface.InterfaceOf<This>, ClusterType.AlteredMandatoryEventKeysOf<AlterationsT>>, ClusterType.AlteredMandatoryAttributeKeysOf<AlterationsT>>>;
    /**
     * Create a new behavior with additional cluster features marked "mandatory".
     *
     * This informs matter.js that an application supports these elements.
     */
    static enable<This extends ClusterBehavior.Type, const FlagsT extends ClusterType.ElementFlags<ClusterInterface.InterfaceOf<This>>>(this: This, flags: FlagsT): ClusterBehavior.Type<This, ClusterType.WithEnabledAttributes<ClusterType.WithEnabledEvents<ClusterInterface.InterfaceOf<This>, ClusterType.EnabledEventKeysOf<FlagsT>>, ClusterType.EnabledAttributeKeysOf<FlagsT>>>;
    /**
     * Returns this behavior type with all cluster elements present regardless of feature selection.
     *
     * This is type-only; at runtime the deconflicted conformance mode already includes all elements.
     */
    static get complete(): ClusterBehavior.Type;
    static isType(type: Behavior.Type): type is ClusterBehavior.Type;
    static supports(other: Behavior.Type): boolean;
    requireAttributeEnabled<This extends Behavior, K extends keyof This["state"]>(this: This, attributeName: K): Exclude<This["state"][K], undefined>;
    assertAttributeEnabled<This extends Behavior, K extends keyof This["state"]>(this: This, attributeName: K): void;
    static Events: typeof Events;
}
export declare namespace ClusterBehavior {
    /**
     * A ClusterBehavior specialized for a specific cluster namespace.
     */
    interface Type<B extends Behavior.Type = Behavior.Type, N extends ClusterTyping = ClusterInterface.InterfaceOf<B>, NS extends ClusterType = ClusterType.Concrete, I = B["Internal"], // inline: B["Internal"]
    ID extends Uncapitalize<string> = B extends {
        readonly id: infer S extends Uncapitalize<string>;
    } ? S : Uncapitalize<string>> {
        new (agent: Agent, backing: BehaviorBacking): Instance<B, N>;
        readonly name: string;
        /**
         * The behavior ID for ClusterBehaviors is the name of the cluster.
         */
        readonly id: ID;
        /**
         * The cluster namespace for this behavior.
         */
        readonly cluster: NS;
        /**
         * Supported features as a flag object.
         */
        readonly features: ClusterType.FeaturesOf<N>;
        readonly Events: ClusterEvents.Type<N, B>;
        readonly State: new () => ClusterState.Type<N, B>;
        readonly Internal: I;
        readonly Interface: N;
        readonly schema: Schema.Cluster;
        readonly early: boolean;
        readonly defaults: ClusterState.Type<N, B>;
        readonly supervisor: RootSupervisor;
        readonly dependencies?: Iterable<Behavior.Type>;
        supports: typeof ClusterBehavior.supports;
        readonly ExtensionInterface: ExtensionInterfaceOf<B>;
        readonly lockOnInvoke: boolean;
        /**
         * Create a new behavior for a specific cluster namespace.
         */
        for<This extends ClusterBehavior.Type, const NS extends ClusterType>(this: This, ns: NS, schema?: Schema, name?: string): ClusterBehavior.Type<This, NS["Typing"], NS> & {
            readonly id: Uncapitalize<NS["name"] & string>;
        };
        /**
         * Create a new behavior with different cluster features.
         */
        withFeatures<This extends ClusterBehavior.Type, const FeaturesT extends ClusterType.FeatureSelection<ClusterInterface.InterfaceOf<This>>>(this: This, ...features: FeaturesT): ClusterBehavior.Type<This, ClusterType.WithSupportedFeatures<ClusterInterface.InterfaceOf<This>, ClusterType.FeaturesAsFlags<ClusterInterface.InterfaceOf<This>, FeaturesT>>>;
        /**
         * Alias for {@link withFeatures}.
         */
        with<This extends ClusterBehavior.Type, const FeaturesT extends ClusterType.FeatureSelection<ClusterInterface.InterfaceOf<This>>>(this: This, ...features: FeaturesT): ClusterBehavior.Type<This, ClusterType.WithSupportedFeatures<ClusterInterface.InterfaceOf<This>, ClusterType.FeaturesAsFlags<ClusterInterface.InterfaceOf<This>, FeaturesT>>>;
        /**
         * Create a new behavior with modified cluster elements.
         */
        alter<This extends ClusterBehavior.Type, const AlterationsT extends ClusterType.Alterations<ClusterInterface.InterfaceOf<This>>>(this: This, alterations: AlterationsT): ClusterBehavior.Type<This, ClusterType.WithEnabledAttributes<ClusterType.WithEnabledEvents<ClusterInterface.InterfaceOf<This>, ClusterType.AlteredMandatoryEventKeysOf<AlterationsT>>, ClusterType.AlteredMandatoryAttributeKeysOf<AlterationsT>>>;
        set<This extends Behavior.Type>(this: This, defaults: Behavior.InputStateOf<This>): This;
        enable<This extends ClusterBehavior.Type, const FlagsT extends ClusterType.ElementFlags<ClusterInterface.InterfaceOf<This>>>(this: This, flags: FlagsT): ClusterBehavior.Type<This, ClusterType.WithEnabledAttributes<ClusterType.WithEnabledEvents<ClusterInterface.InterfaceOf<This>, ClusterType.EnabledEventKeysOf<FlagsT>>, ClusterType.EnabledAttributeKeysOf<FlagsT>>>;
    }
    /**
     * A fully-typed ClusterBehavior.  This type is derived by combining properties of the base type with properties
     * contributed by the cluster.
     */
    type Instance<B extends Behavior.Type, N extends ClusterTyping> = ClusterBehavior & Omit<InstanceType<B>, "cluster" | "state" | "events" | "initialize" | typeof Symbol.asyncDispose | keyof ClusterInterface.MethodsOf<ClusterInterface.InterfaceOf<B>> | keyof ExtensionInterfaceOf<B>> & ClusterInterface.MethodsOf<N> & ExtensionInterfaceOf<B> & {
        /**
         * The cluster namespace.
         */
        cluster: ClusterType.Concrete;
        /**
         * State values for the behavior.
         */
        readonly state: ClusterState<N, B>;
        /**
         * Observables for cluster events and attribute changes.
         */
        readonly events: ClusterEvents<N, B>;
        /**
         * Supported features as a flag object.
         */
        readonly features: ClusterType.FeaturesOf<N>;
        [Symbol.asyncDispose](): MaybePromise<void>;
    };
    /**
     * A behavior type with all cluster elements exposed regardless of feature selection.
     *
     * Used by client behaviors to provide access to all commands, attributes, and events.
     */
    interface Complete<B extends Behavior.Type = Behavior.Type, NS extends ClusterType = ClusterType.Concrete> extends Omit<Type<B, NS["Typing"], NS>, "new" | "Events" | "State"> {
        new (agent: Agent, backing: BehaviorBacking): CompleteInstance<B, NS["Typing"]>;
        readonly Events: ClusterEvents.CompleteType<NS["Typing"], B>;
        readonly State: new () => ClusterState.Complete<NS["Typing"], B>;
    }
    /**
     * A fully-typed instance with all cluster elements present regardless of feature selection.
     */
    type CompleteInstance<B extends Behavior.Type, N extends ClusterTyping> = ClusterBehavior & Omit<InstanceType<B>, "cluster" | "state" | "events" | "initialize" | typeof Symbol.asyncDispose | keyof ClusterInterface.MethodsOf<ClusterInterface.InterfaceOf<B>> | keyof ExtensionInterfaceOf<B>> & ClusterInterface.AllMethodsOf<N> & ExtensionInterfaceOf<B> & {
        cluster: ClusterType.Concrete;
        readonly state: ClusterState.Complete<N, B>;
        readonly events: ClusterEvents.Complete<N, B>;
        readonly features: ClusterType.FeaturesOf<N>;
        [Symbol.asyncDispose](): MaybePromise<void>;
    };
    /**
     * This is an unfortunate kludge required to work around https://github.com/microsoft/TypeScript/issues/27965.  It
     * allows you to designate extension methods available on behavior instances.
     *
     * Methods designated in this way make it so you can override methods using the syntax:
     *
     *     override foo() {}
     *
     * rather than:
     *
     *     override foo: () => {}
     *
     * This is also required for protected properties because TypeScript doesn't include them in the mapped types our
     * typing system uses to define modified behaviors.
     *
     * See {@link ClusterInterface} for more details.
     */
    const ExtensionInterface: {};
    function is(type: Behavior.Type): type is ClusterBehavior.Type;
}
//# sourceMappingURL=ClusterBehavior.d.ts.map