"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const matter_server_1 = require("../modules/matter-server");
const ts_deferred_1 = require("ts-deferred");
function default_1(RED) {
    function MatterServerNode(config) {
        const node = this;
        RED.nodes.createNode(node, config);
        const devices = new Map();
        RED.nodes.eachNode((n) => {
            if (n.server === node.id) {
                devices.set(n.id, false);
            }
        });
        const nodeRedFolderPath = RED.settings.userDir;
        const serverInit = new ts_deferred_1.Deferred();
        const serverStart = new ts_deferred_1.Deferred();
        node.serverPromise = serverStart.promise;
        const matterServer = new matter_server_1.MatterServer();
        matterServer
            .init({
            storageLocation: `${nodeRedFolderPath}/node-red-matter/matter-servers/${node.id}`,
        })
            .then(() => {
            serverInit.resolve();
        });
        if (devices.size === 0) {
            serverInit.promise.then(() => {
                node.log('Starting matter server');
                matterServer.start().then(() => {
                    serverStart.resolve(matterServer.matterServer);
                });
            });
        }
        node.addListener('add_commissioning_server', async (nodeId, commissioningServer) => {
            await serverInit.promise;
            devices.set(nodeId, true);
            try {
                matterServer.addCommissioningServer(commissioningServer);
                node.log(`Added commissioning server for ${nodeId}`);
            }
            catch (e) {
                node.error(e);
            }
            // Only start the server after all the devices have been added or failed to be added
            if (Array.from(devices.values()).every((value) => value)) {
                node.log('Starting matter server');
                await matterServer.start();
                serverStart.resolve(matterServer.matterServer);
            }
        });
        node.addListener('add_commissioning_controller', async (nodeId, commissioningController) => {
            await serverInit.promise;
            devices.set(nodeId, true);
            matterServer.addCommissioningController(commissioningController);
            // Only start the server after all the devices have been added or failed to be added
            if (Array.from(devices.values()).every((value) => value)) {
                node.log('Starting matter server');
                await matterServer.start();
                try {
                    await commissioningController.connect();
                }
                catch (e) {
                    node.error(e);
                }
                serverStart.resolve(matterServer.matterServer);
            }
        });
        node.on('close', async (done) => {
            node.log('Stopping matter server');
            await serverInit.promise;
            await matterServer.stop();
            done();
        });
    }
    RED.nodes.registerType('matter-server', MatterServerNode);
}
exports.default = default_1;
