"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const handlebars_1 = __importDefault(require("handlebars"));
const fs_1 = __importDefault(require("fs"));
const logger_1 = __importDefault(require("../logger"));
const ws_1 = __importDefault(require("ws"));
/**
 * Parser class for Websocket Protocol mocks
 */
class WebsocketParser {
    /**
     *
     * @param {any} wss Instance of WebSocket server
     */
    constructor(wss) {
        /**
         * Compiles and transforms the handlerbars in a given mockfile and according to the key, i.e.
         * - broadcast
         * - emit; or
         * - self
         * sends the message from message.mock
         * If it's the first message to be sent after connection, mockfile would be connection.mock
         * @param {string} mockFile mockFile for the current connection
         * @param {WebSocket} ws current socket
         * @param {IncomingMessage} request incoming request
         * @param {any} incomingMessage incoming data
         */
        this.send = (mockFile, ws, request, incomingMessage) => {
            const template = handlebars_1.default.compile(fs_1.default.readFileSync(mockFile).toString());
            let message;
            let delay;
            try {
                message = JSON.parse(template({ request: request, message: incomingMessage }));
                delay = message.delay || 0;
                logger_1.default.debug(`Delay set to ${delay}`);
                if (message.broadcast) {
                    this.wss.clients.forEach(function each(client) {
                        if (client.readyState === ws_1.default.OPEN) {
                            setTimeout(() => {
                                client.send(message.broadcast);
                                logger_1.default.debug(`Responded with ${message.broadcast}`);
                            }, delay);
                        }
                    });
                }
                if (message.self) {
                    setTimeout(() => {
                        ws.send(message.self);
                        logger_1.default.debug(`Responded with ${message.self}`);
                    }, delay);
                }
                if (message.emit) {
                    this.wss.clients.forEach((client) => {
                        if (client !== ws && client.readyState === ws_1.default.OPEN) {
                            setTimeout(() => {
                                client.send(message.emit);
                                logger_1.default.debug(`Responded with ${message.emit}`);
                            }, delay);
                        }
                    });
                }
            }
            catch (e) {
                logger_1.default.error(e.message);
            }
        };
        /**
         * Sends a list of current clients connected to the server, id of the new client, and status (joining or leaving)
         * @param {WebSocket} ws current socket
         * @param {IncomingMessage} request Incoming request
         * @param {string[]} clients List of existin clients
         * @param {string} clientId new clientId
         * @param {string} status joining or leaving
         * @param {string} mockFile mockfile, i.e. connection.mock
         */
        this.sendConnect = (ws, request, clients, clientId, status, mockFile) => {
            let clientsInfo = {
                clients: clients,
                client: clientId,
                status: status,
            };
            if (mockFile) {
                this.send(mockFile, ws, request);
                logger_1.default.debug(`Added client ${clientId}`);
            }
            else {
                if (status === "joining") {
                    logger_1.default.warn(`No suitable connection.mock file found for ${request.url}`);
                }
            }
            this.wss.clients.forEach(function each(client) {
                if (client.readyState === ws_1.default.OPEN) {
                    client.send(JSON.stringify(clientsInfo));
                }
            });
        };
        this.wss = wss;
    }
}
exports.default = WebsocketParser;
//# sourceMappingURL=WebsocketParser.js.map