import { Bytes, isUint8Array } from "@zwave-js/shared";
import { isArray, isObject } from "alcalzone-shared/typeguards";
const domain = "_zwave._tcp.local";
export async function discoverRemoteSerialPorts(timeout = 1000) {
    const { default: createMDNSServer } = await import("mdns-server");
    const mdns = createMDNSServer({
        reuseAddr: true,
        loopback: false,
        noInit: true,
        ttl: 10,
    });
    let timer;
    return new Promise((resolve, reject) => {
        mdns.on("response", (resp) => {
            const matches = resp.answers
                .filter((n) => n.type === "PTR"
                && n.name === domain
                && typeof n.data === "string")
                .map(({ data }) => {
                return {
                    txt: resp.answers.find((n) => n.type === "TXT" && n.name === data) ?? resp.additionals.find((n) => n.type === "TXT" && n.name === data),
                    srv: resp.answers.find((n) => n.type === "SRV" && n.name === data) ?? resp.additionals.find((n) => n.type === "SRV" && n.name === data),
                };
            })
                .filter(({ srv }) => !!srv
                && isObject(srv.data)
                && typeof srv.data.target === "string"
                && typeof srv.data.port === "number")
                .map(({ txt, srv }) => {
                const info = {};
                if (!!txt && isArray(txt.data)) {
                    const strings = txt.data
                        .filter((d) => isUint8Array(d))
                        .map((d) => Bytes.view(d).toString("utf8"))
                        .filter((d) => d.includes("="));
                    for (const string of strings) {
                        const [key, value] = string.split("=", 2);
                        info[key] = value;
                    }
                }
                const addr = srv.data;
                const port = `tcp://${addr.target}:${addr.port}`;
                return {
                    port,
                    info,
                };
            });
            if (matches.length) {
                clearTimeout(timer);
                resolve(matches);
            }
        });
        mdns.on("ready", () => {
            mdns.query([
                { name: domain, type: "PTR" },
                { name: domain, type: "SRV" },
                { name: domain, type: "TXT" },
            ]);
        });
        mdns.on("error", reject);
        mdns.initServer();
        if (typeof timeout === "number" && timeout > 0) {
            timer = setTimeout(() => {
                mdns.destroy();
                resolve(undefined);
            }, timeout);
        }
    });
}
//# sourceMappingURL=node.js.map