/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { type DnsRecord } from "#codec/DnsCodec.js";
import { Duration } from "#time/Duration.js";
import { Entropy } from "#util/Entropy.js";
import { Lifetime } from "#util/Lifetime.js";
import { Observable } from "#util/Observable.js";
import { DnssdName } from "./DnssdName.js";
import { QueryMulticaster } from "./DnssdSolicitor.js";
import { MdnsSocket } from "./MdnsSocket.js";
/**
 * Names collected via DNS-SD.
 *
 * TODO - API is designed to support Avahi, Bonjour etc. but current implementation is tied to local MDNS
 */
export declare class DnssdNames {
    #private;
    constructor({ socket, lifetime, entropy, filter, filterNames, goodbyeProtectionWindow, minTtl, ttlGraceFactor }: DnssdNames.Context);
    /**
     * Test for existence of name.
     */
    has(name: string): boolean;
    /**
     * Retrieve the {@link DnssdName} for {@link name}.
     *
     * This will create the name if it does not exist, and if you do not add an observer then it will not automatically
     * delete if there are no records.  So if you may not use the record test for existence with {@link has} first.
     */
    get(qname: string): DnssdName;
    /**
     * Retrieve the {@link DnssdName} if known.
     */
    maybeGet(name: string): DnssdName | undefined;
    /**
     * All currently discovered {@link DnssdName}s.
     */
    get discoveredNames(): Iterable<DnssdName>;
    /**
     * Wait for all workers and close all names.
     */
    close(): Promise<void>;
    /**
     * Dynamic ingress filters. Records accepted by ANY registered filter are processed; with no filters, all records
     * are accepted. Pass the names a filter accepts (e.g. its service types) so the socket can drop irrelevant packets
     * before decoding them; a filter added without names disables that optimization (the socket accepts everything).
     */
    get filters(): DnssdNames.Filters;
    get socket(): MdnsSocket;
    /**
     * Emits when a {@link DnssdName} is first discovered.
     */
    get discovered(): Observable<[name: DnssdName], void>;
    /**
     * Shared solicitor.
     *
     * We offer solicitation in this object so there is not redundant solicitation across interested parties.
     */
    get solicitor(): QueryMulticaster;
    get entropy(): Entropy;
}
export declare namespace DnssdNames {
    interface Context {
        socket: MdnsSocket;
        lifetime?: Lifetime.Owner;
        entropy: Entropy;
        /**
         * Initial ingress filter. Additional filters may be added via {@link DnssdNames.filters}.
         *
         * Observed names are considered relevant even if filtered here.
         */
        filter?: (record: DnsRecord) => boolean;
        /**
         * Names the initial {@link filter} accepts (e.g. its DNS-SD service types), driving the socket's pre-decode
         * relevance filter. Pass `"all"` (or omit) only when interest cannot be enumerated — note that disables the
         * pre-filter for the whole socket (every packet is fully decoded again), so prefer concrete names.
         */
        filterNames?: Iterable<string> | "all";
        /**
         * The interval after discovering a record for which we ignore goodbyes.
         *
         * This serves as protection for out-of-order messages when a device expires then broadcasts the same record
         * in a very short amount of time.
         */
        goodbyeProtectionWindow?: Duration;
        /**
         * Minimum TTL for PTR records.
         */
        minTtl?: Duration;
        /**
         * Multiplier applied to record TTL when computing expiry to tolerate timing jitter.  Must be >= 1.0.
         * Defaults to {@link DEFAULT_TTL_GRACE_FACTOR}.
         */
        ttlGraceFactor?: number;
    }
    /**
     * Set-like facade over the ingress filters that also captures the names each filter accepts (see
     * {@link DnssdNames.filters}).
     */
    interface Filters {
        /**
         * Register an ingress filter together with the names it accepts. `names` drives the socket's pre-decode
         * relevance filter, so it is required: pass the filter's DNS-SD service types (e.g. `_meshcop._udp.local`).
         *
         * **Avoid `"all"` unless unavoidable.** It does not merely disable the optimization for this scanner — it
         * disables it for the WHOLE socket, forcing every inbound mDNS packet to be fully decoded again (the exact
         * cost the pre-filter exists to avoid). Only use it when the filter's interest genuinely cannot be enumerated.
         */
        add(filter: (record: DnsRecord) => boolean, names: Iterable<string> | "all"): void;
        delete(filter: (record: DnsRecord) => boolean): boolean;
        has(filter: (record: DnsRecord) => boolean): boolean;
        readonly size: number;
        [Symbol.iterator](): IterableIterator<(record: DnsRecord) => boolean>;
    }
    const defaults: {
        goodbyeProtectionWindow: Duration;
        minTtl: Duration;
    };
}
//# sourceMappingURL=DnssdNames.d.ts.map