import { Log } from './Logger';
module.exports = new class WebSocket {
    constructor() { }
    start(server, callback) {
        Log('info', 'Preparing WebSocket');
        this.io = require('socket.io')(server);
        this.listeners();
        var port = Config.ports.http;
        server.listen(port, () => {
            Log('info', `WebServer & WebSocket running at port ${port}`);
            callback();
        });
    }
    listeners() {
        this.io.on('connection', (socket) => {
            Log('info', 'Client connected');
            socket.on('init', (page) => {
                if ([
                    'home'
                ].includes(page)) {
                    socket.join(page);
                    switch (page) {
                        case 'home':
                            socket.emit('quality', Undecked.quality);
                            socket.emit('pagelist', Undecked.Pages.getNames());
                            break;
                    }
                }
            });
            socket.on('page', (query, ...args) => {
                switch (query) {
                    case 'request':
                        var pageID = args[0];
                        var callback = args[1];
                        if (Undecked.Pages.exists(pageID)) {
                            var page = Undecked.Pages.get(pageID);
                            callback(null, page.export());
                        }
                        else
                            callback('Page does not exist.');
                        break;
                    case 'setname':
                        var pageID = args[0];
                        var newName = args[1];
                        if (Undecked.Pages.exists(pageID)) {
                            var page = Undecked.Pages.get(pageID);
                            page.setName(newName);
                        }
                        break;
                    case 'setkey':
                        var pageID = args[0];
                        var x = args[1];
                        var y = args[2];
                        var key = args[3];
                        var responseToken = args[4];
                        if (Undecked.Pages.exists(pageID)) {
                            var page = Undecked.Pages.get(pageID);
                            page.updateKey(x, y, key, responseToken);
                        }
                        break;
                    case 'getkey':
                        var pageID = args[0];
                        var x = args[1];
                        var y = args[2];
                        var getkey_callback = args[3];
                        if (Undecked.Pages.exists(pageID)) {
                            var page = Undecked.Pages.get(pageID);
                            if (page.hasKey(x, y))
                                getkey_callback(page.requestKey(x, y));
                        }
                        break;
                    case 'executekey':
                        var pageID = args[0];
                        var x = args[1];
                        var y = args[2];
                        if (Undecked.Pages.exists(pageID)) {
                            var page = Undecked.Pages.get(pageID);
                            if (page.hasKey(x, y)) {
                                if (page.getKey(x, y).actions != undefined &&
                                    page.getKey(x, y).actions.up != undefined) {
                                    Undecked.Integrations.executeActions(page.getKey(x, y).actions.up, null);
                                }
                            }
                        }
                        break;
                    case 'create':
                        var pageName = args[0];
                        Undecked.Pages.create(pageName, () => Undecked.WebSocket.broadcastTo('home', 'pagelist', Undecked.Pages.getNames()));
                        break;
                    case 'setorder':
                        var order = args[0];
                        if (typeof order.includes == 'function')
                            Undecked.Pages.setOrder(order);
                        break;
                    case 'operation':
                        var operation = args[0];
                        var originPageID = args[1];
                        var originX = args[2];
                        var originY = args[3];
                        var destinationPageID = args[4];
                        var destinationX = args[5];
                        var destinationY = args[6];
                        Undecked.Pages.handleOperation(operation, originPageID, originX, originY, destinationPageID, destinationX, destinationY);
                        break;
                }
            });
            socket.on('actioneditor', (query, ...args) => {
                switch (query) {
                    case 'start':
                        var settings = args[0];
                        var callback = args[1];
                        var pageID = settings.pageID;
                        var keyX = settings.keyX;
                        var keyY = settings.keyY;
                        var start = () => {
                            var response = Undecked.Integrations.startEditor(settings);
                            callback(response.error, response.actionEditorID);
                        };
                        var page = Undecked.Pages.get(pageID);
                        if (page && page.hasKey(keyX, keyY)) {
                            var key = page.getKey(keyX, keyY);
                            if (key.state != undefined && key.state.type == 'ghost') {
                                if (key.state.masterID != undefined) {
                                    var masterLocation = Undecked.Pages.KeyManager.getLocation(key.state.masterID);
                                    var masterPage = Undecked.Pages.get(masterLocation.pageID);
                                    if (masterPage) {
                                        var masterKey = masterPage.getKey(masterLocation.x, masterLocation.y);
                                        if (masterKey.state != undefined &&
                                            masterKey.state.ghostIDs != undefined &&
                                            masterKey.state.ghostIDs.includes(key.id)) {
                                            settings.pageID = masterLocation.pageID;
                                            settings.keyX = masterLocation.x;
                                            settings.keyY = masterLocation.y;
                                            start();
                                        }
                                    }
                                }
                            }
                            else
                                start();
                        }
                        break;
                    case 'remove':
                        var pageID = args[0];
                        var x = args[1];
                        var y = args[2];
                        var actionInstanceID = args[3];
                        var type = args[4];
                        var remove = (key) => {
                            if (key.actions != undefined && key.actions[type] != undefined) {
                                if (key.actions[type][actionInstanceID] != undefined) {
                                    delete key.actions[type][actionInstanceID];
                                    page.save();
                                }
                            }
                        };
                        if (Undecked.Pages.exists(pageID)) {
                            var page = Undecked.Pages.get(pageID);
                            if (page.hasKey(x, y)) {
                                var key = page.getKey(x, y);
                                if (key.state != undefined && key.state.type == 'ghost') {
                                    if (key.state.masterID != undefined) {
                                        var masterLocation = Undecked.Pages.KeyManager.getLocation(key.state.masterID);
                                        var masterPage = Undecked.Pages.get(masterLocation.pageID);
                                        if (masterPage) {
                                            var masterKey = masterPage.getKey(masterLocation.x, masterLocation.y);
                                            if (masterKey.state != undefined &&
                                                masterKey.state.ghostIDs != undefined &&
                                                masterKey.state.ghostIDs.includes(key.id))
                                                remove(masterKey);
                                        }
                                    }
                                }
                                else
                                    remove(key);
                            }
                        }
                        break;
                    case 'create':
                        var pageID = args[0];
                        var x = args[1];
                        var y = args[2];
                        var createtype = args[3];
                        var integrationID = args[4];
                        var actionID = args[5];
                        var createCallback = args[6];
                        var create = (key) => {
                            if (key.actions == undefined)
                                key.actions = { up: {}, down: {}, latch: {}, unlatch: {} };
                            if (key.actions[createtype] == undefined)
                                key.actions[createtype] = {};
                            var newActionInstanceID = Undecked.generateRandom(8, (checkValid) => {
                                return key.actions[createtype][checkValid] == undefined;
                            });
                            key.actions[createtype][newActionInstanceID] = {
                                integrationID,
                                actionID,
                                actionInstanceID: newActionInstanceID,
                                properties: {},
                                logs: []
                            };
                            createCallback(key.actions[createtype][newActionInstanceID]);
                        };
                        if (Undecked.Integrations.exists(integrationID)) {
                            var integration = Undecked.Integrations.get(integrationID);
                            if (integration.api.hasAction(actionID)) {
                                if (Undecked.Pages.exists(pageID)) {
                                    var page = Undecked.Pages.get(pageID);
                                    if (page.hasKey(x, y)) {
                                        var key = page.getKey(x, y);
                                        if (key.state != undefined && key.state.type == 'ghost') {
                                            if (key.state.masterID != undefined) {
                                                var masterLocation = Undecked.Pages.KeyManager.getLocation(key.state.masterID);
                                                var masterPage = Undecked.Pages.get(masterLocation.pageID);
                                                if (masterPage) {
                                                    var masterKey = masterPage.getKey(masterLocation.x, masterLocation.y);
                                                    if (masterKey.state != undefined &&
                                                        masterKey.state.ghostIDs != undefined &&
                                                        masterKey.state.ghostIDs.includes(key.id))
                                                        create(masterKey);
                                                }
                                            }
                                        }
                                        else
                                            create(key);
                                    }
                                }
                            }
                        }
                        break;
                    case 'instance':
                        var actionEditorID = args[0];
                        var instanceQuery = args[1];
                        if (Undecked.Integrations.editorExists(actionEditorID)) {
                            var EditorWrapper = Undecked.Integrations.getEditor(actionEditorID);
                            switch (instanceQuery) {
                                case 'ready':
                                    EditorWrapper.ready();
                                    break;
                                case 'fields':
                                    var fields = args[2];
                                    if (typeof EditorWrapper.editor._change == 'function')
                                        EditorWrapper.editor._change(fields);
                                    break;
                                case 'close':
                                    EditorWrapper.destroy();
                                    break;
                            }
                        }
                        break;
                }
            });
            socket.on('connections', (query, ...args) => {
                switch (query) {
                    case 'request':
                        var integrationID = args[0];
                        var connectionType = args[1];
                        var requestCallback = args[2];
                        var fields = Undecked.Connections.getConnectionRequestData(integrationID, connectionType);
                        requestCallback(fields);
                        break;
                    case 'create':
                        var integrationID = args[0];
                        var connectionType = args[1];
                        var properties = args[2];
                        var createCallback = args[3];
                        Undecked.Connections.create(integrationID, connectionType, properties, createCallback);
                        break;
                    default:
                        break;
                }
            });
        });
    }
    broadcastTo(group, header, ...args) {
        if (this.io)
            this.io.to(group).emit(header, ...args);
    }
    broadcast(header, ...args) {
        if (this.io)
            this.io.emit(header, ...args);
    }
}();
//# sourceMappingURL=WebSocket.js.map