"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const matter_device_1 = require("../modules/matter-device");
var DeviceCategory;
(function (DeviceCategory) {
    DeviceCategory["standalone"] = "standalone";
    DeviceCategory["aggregated"] = "aggregated";
})(DeviceCategory || (DeviceCategory = {}));
function default_1(RED) {
    RED.httpAdmin
        .route('/node-red-matter/device/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 MatterDeviceNode(config) {
        const node = this;
        RED.nodes.createNode(node, config);
        const server = RED.nodes.getNode(config.server);
        const aggregator = RED.nodes.getNode(config.aggregator);
        const matterDevice = new matter_device_1.MatterOnOffDevice(config.devicetype, Number(config.port), node.id, Number(config.discriminator), Number(config.productid ?? 0x8000));
        node.device = matterDevice;
        matterDevice
            .start({
            aggregated: config.devicecategory === DeviceCategory.aggregated,
            onStatusChange: (status) => {
                const message = {
                    type: config.devicetype,
                    name: matterDevice.deviceName,
                    id: matterDevice.device?.id,
                    status,
                };
                node.emit('status_change', message);
            },
        })
            .then(async (commissioningServer) => {
            // Register device to Matter server
            if (config.devicecategory === DeviceCategory.standalone &&
                server == null) {
                node.error(`Matter server ${config.server} not found`);
                return;
            }
            else if (config.devicecategory === DeviceCategory.aggregated &&
                aggregator == null) {
                node.error(`Matter aggregator ${config.aggregator} not found`);
                return;
            }
            if (commissioningServer != null) {
                await server.serverPromise;
                server.emit('add_commissioning_server', node.id, commissioningServer);
            }
            else {
                aggregator.emit('add_bridged_device', node.id, matterDevice);
                await aggregator.server.serverPromise;
            }
            if (commissioningServer != null) {
                const message = await matterDevice.getPairingData();
                // Store pairing code
                node.qrcode = message.qrCode;
                node.manualPairingCode = message.manualPairingCode;
                node.commissioned = message.commissioned;
            }
            // Handle device updates
            if (matterDevice.device == null) {
                return;
            }
            switch (config.devicetype) {
                case matter_device_1.DeviceType.OnOffLightDevice:
                case matter_device_1.DeviceType.OnOffPluginUnitDevice:
                    matterDevice.device.isOn().then((status) => {
                        const updateStatusMessage = {
                            type: config.devicetype,
                            name: matterDevice.deviceName,
                            id: matterDevice.device?.id,
                            status,
                        };
                        node.emit('status_change', updateStatusMessage);
                    });
                    break;
                default:
                    node.warn(`Unknown device type ${config.devicetype}`);
            }
        });
        // Receive status change requests from matter-device-control nodes
        node.addListener('change_status', (status) => {
            if (matterDevice.device == null) {
                return;
            }
            switch (config.devicetype) {
                case matter_device_1.DeviceType.OnOffLightDevice:
                case matter_device_1.DeviceType.OnOffPluginUnitDevice:
                    if (typeof status !== 'boolean') {
                        node.warn(`Invalid status ${status} for device type ${config.devicetype}`);
                        return;
                    }
                    matterDevice.device.onOff(status);
                    break;
                default:
                    node.warn(`Unknown device type ${config.devicetype}`);
            }
        });
    }
    RED.nodes.registerType('matter-device', MatterDeviceNode);
}
exports.default = default_1;
