#include settings.js

const UmiWebSocket = function(server, message, useWorker) {
    if(typeof useWorker === 'undefined')
        useWorker = (function() {
            // Overrides
            if(Umi.Settings.get('neverUseWorker'))
                return false;
            if(Umi.Settings.get('forceUseWorker'))
                return true;

            // Detect chromosomes
            if((!!window.chrome || (!!window.Intl && !!Intl.v8BreakIterator)) && 'CSS' in window)
                return true;

            // Phones
            if((/iphone|ipod|android|ie|blackberry|fennec/i).test(navigator.userAgent.toLowerCase()))
                return true;

            return false;
        })();

    let send, close, sendInterval, clearIntervals;

    if(useWorker) {
        const worker = new Worker(MAMI_WS);
        worker.addEventListener('message', function(ev) {
            message(ev.data);
        });
        worker.postMessage({act: 'ws:open', server: server});
        send = function(text) {
            worker.postMessage({act: 'ws:send', text: text});
        };
        close = function() {
            worker.postMessage({act: 'ws:close'});
        };
        getIntervals = function() {
            worker.postMessage({act: 'ws:intervals'});
        };
        sendInterval = function(text, interval) {
            worker.postMessage({act: 'ws:send_interval', text: text, interval: interval});
        };
        clearIntervals = function() {
            worker.postMessage({act: 'ws:clear_intervals'});
        };
    } else {
        const websocket = new WebSocket(server), intervals = [];
        websocket.addEventListener('open', function(ev) {
            message({
                act: 'ws:open',
                type: ev.type,
                timeStamp: ev.timeStamp,
                isTrusted: ev.isTrusted,
            });
        });
        websocket.addEventListener('close', function(ev) {
            message({
                act: 'ws:close',
                type: ev.type,
                timeStamp: ev.timeStamp,
                isTrusted: ev.isTrusted,
                code: ev.code,
                reason: ev.reason,
                wasClean: ev.wasClean,
            });
        });
        websocket.addEventListener('error', function(ev) {
            message({
                act: 'ws:error',
                type: ev.type,
                timeStamp: ev.timeStamp,
                isTrusted: ev.isTrusted,
            });
        });
        websocket.addEventListener('message', function(ev) {
            message({
                act: 'ws:message',
                type: ev.type,
                timeStamp: ev.timeStamp,
                isTrusted: ev.isTrusted,
                data: ev.data,
                origin: ev.origin,
                lastEventId: ev.lastEventId,
            });
        });
        send = function(text) {
            websocket.send(text);
        };
        close = function() {
            websocket.close();
        };
        getIntervals = function() {
            return intervals;
        };
        sendInterval = function(text, interval) {
            intervals.push(setInterval(function() {
                if(websocket)
                    websocket.send(text);
            }, interval));
        };
        clearIntervals = function() {
            for(let i = 0; i < intervals.length; ++i)
                clearInterval(intervals[i]);
        };
    }

    return {
        isUsingWorker: useWorker,
        send: send,
        close: close,
        getIntervals: getIntervals,
        sendInterval: sendInterval,
        clearIntervals: clearIntervals,
    };
};
