"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const matter_aggregator_1 = require("../modules/matter-aggregator");
const ObservableMap_1 = require("../utils/ObservableMap");
function default_1(RED) {
    RED.httpAdmin
        .route('/node-red-matter/aggregator/pairingcode')
        .get(function (req, res) {
        const deviceId = req.query['device-id'];
        const node = RED.nodes.getNode(deviceId);
        if (node == null) {
            res.status(404).send('Device not found');
            return;
        }
        const message = {
            commissioned: node.commissioned,
            qrcode: node.qrcode,
            manualPairingCode: node.manualPairingCode,
        };
        res.json(message);
    });
    function MatterAggregatorNode(config) {
        const node = this;
        RED.nodes.createNode(node, config);
        const server = RED.nodes.getNode(config.server);
        node.server = server;
        const matterDevice = new matter_aggregator_1.MatterAggregator(Number(config.port), node.id, Number(config.discriminator), Number(config.productid ?? 0x8000));
        const devices = new ObservableMap_1.ObservableMap();
        RED.nodes.eachNode((n) => {
            if (n.aggregator === node.id) {
                devices.set(n.id, false);
            }
        });
        console.log(devices);
        const matterDevices = [];
        node.addListener('add_bridged_device', async (id, device) => {
            node.log(`Adding device ${id} to aggregator`);
            matterDevices.push(device);
            devices.set(id, true);
        });
        if (devices.size === 0) {
            startAggregator();
        }
        const timeout = setTimeout(() => {
            node.warn('Not all devices were added to the aggregator, starting anyway but in a potentially unstable state');
            startAggregator();
        }, 8000);
        devices.addListener(async (devices) => {
            // Only start the server after all the devices have been added or failed to be added
            if (Array.from(devices.values()).every((value) => value)) {
                clearTimeout(timeout);
                node.log(`All devices added (${devices.size}/${devices.size})`);
                startAggregator();
            }
            else {
                const addedDevices = Array.from(devices.values()).filter((value) => value === true).length;
                node.log(`Waiting for all bridged devices to be added (${addedDevices}/${devices.size})`);
            }
        });
        function startAggregator() {
            node.log('Starting matter aggregator');
            matterDevice
                .start({ devices: matterDevices })
                .then(async (commissioningServer) => {
                // Register device to Matter server
                node.log(`Registering device to Matter server ${config.server}`);
                if (server == null) {
                    node.warn(`Matter server ${config.server} not found`);
                    return;
                }
                server.emit('add_commissioning_server', node.id, commissioningServer);
                await server.serverPromise;
                const message = await matterDevice.getPairingData();
                // Store pairing code
                node.qrcode = message.qrCode;
                node.manualPairingCode = message.manualPairingCode;
                node.commissioned = message.commissioned;
            });
        }
    }
    RED.nodes.registerType('matter-aggregator', MatterAggregatorNode);
}
exports.default = default_1;
