/* lib/browser/utilities/webSocket - Handles web socket events and associated errors. This where most communications from outside the browser are processed. */ import browser from "./browser.js";
import network from "./network.js";
/**
 * Module definition for browser-side websocket handling.
 * ```typescript
 * interface module_browserSocket {
 *     error: () => void;                                                          // An error handling method.
 *     hash : string;                                                              // Stores a hash value used to authenticate a client hash tunnel at the server.
 *     send : (data:socketData) => void;                                           // Packages micro-service data for transmission in the application's micro-service format.
 *     sock : websocket_local;                                                     // Provides a web socket object in a way that allows for explicit type declarations, reuse, and without angering the TypeScript gods.
 *     start: (callback: () => void, hashDevice:string, type:string) => WebSocket; // Initiates a web socket client from the browser.
 *     type : string;                                                              // Stores the submitted type value.
 * }
 * ``` */ const webSocket = {
    error: function browser_utilities_socketError() {
        setTimeout(function browser_utilities_socketError_delay() {
            webSocket.start(null, webSocket.hash, webSocket.type);
        }, browser.ui.statusTime);
    },
    hash: "",
    send: null,
    sock: function browser_utilities_socket() {
        // A minor security circumvention.
        const socket = WebSocket;
        // eslint-disable-next-line
        WebSocket = null;
        return socket;
    }(),
    start: function browser_utilities_webSocket(callback, hashDevice, type) {
        const title = document.getElementById("title-bar"), scheme = location.protocol.toLowerCase() === "http:" ? "ws" : "wss", socket = new webSocket.sock(`${scheme}://localhost:${browser.network.ports.ws}/`, [
            `${type}-${hashDevice}`
        ]), open = function browser_utilities_webSocket_socketOpen() {
            if (title.getAttribute("class") === "title offline") {
                location.reload();
            } else {
                title.setAttribute("class", "title");
                if (type === "primary") {
                    const messageDelay = function browser_init_complete_messageDelay() {
                        if (browser.loadQueue.length > 0) {
                            network.send(browser.loadQueue[0].data, browser.loadQueue[0].service);
                            browser.loadQueue.splice(0, 1);
                            if (browser.loadQueue.length > 0) {
                                setTimeout(browser_init_complete_messageDelay, 5);
                            }
                        }
                    };
                    browser.socket = socket;
                    messageDelay();
                }
                socket.type = type;
                if (callback !== null) {
                    callback();
                }
            }
        }, close = function browser_utilities_webSocket_socketClose() {
            if (browser.identity.hashDevice !== "" && socket.type === "primary") {
                const device = document.getElementById(browser.identity.hashDevice), agentList = document.getElementById("agentList"), active = agentList.getElementsByClassName("status-active");
                let a = active.length;
                if (a > 0) {
                    do {
                        a = a - 1;
                        active[a].parentNode.setAttribute("class", "offline");
                    }while (a > 0)
                }
                browser.socket = null;
                title.setAttribute("class", "title offline");
                title.getElementsByTagName("h1")[0].appendText("Disconnected.", true);
                webSocket.send = null;
                if (device !== null) {
                    device.setAttribute("class", "offline");
                }
            }
        }, message = function browser_utilities_webSocket_message(event) {
            if (typeof event.data !== "string") {
                return;
            }
            network.receive(event.data);
        };
        webSocket.hash = hashDevice;
        webSocket.type = type;
        /* Handle Web Socket responses */ socket.onopen = open;
        socket.onmessage = message;
        socket.onclose = close;
        socket.onerror = function browser_utilities_webSocket_error() {
            webSocket.error();
        };
        // do not put a console.log in this function without first removing the log service from /lib/browser/index.ts
        // otherwise this will produce a race condition with feedback loop
        webSocket.send = function browser_utilities_webSocket_sendWrapper(data) {
            // connecting
            if (browser.socket.readyState === 0) {
                setTimeout(function browser_utilities_webSocket_sendWrapper_delay() {
                    browser_utilities_webSocket_sendWrapper(data);
                }, 10);
            }
            // open
            if (browser.socket.readyState === 1) {
                browser.socket.send(JSON.stringify(data));
            }
        };
        return browser.socket;
    },
    type: ""
};
export default webSocket;
