var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.IntegrationsManager = void 0;
var path = require("path");
var Logger_1 = require("../Logger");
var IntegrationApi_1 = require("./IntegrationApi");
var EditorAPI_1 = require("./EditorAPI");
var fs = require("fs-extra");
var ensureDir = fs.ensureDir, pathExists = fs.pathExists, readdir = fs.readdir, readJSON = fs.readJSON, readJson = fs.readJson;
var IntegrationsManager = /** @class */ (function () {
    function IntegrationsManager() {
        this.integrations = {};
        this.openEditors = {};
    }
    IntegrationsManager.prototype.load = function (callback) {
        var _this = this;
        (0, Logger_1.Log)('info', 'Loading integrations');
        ensureDir(path.join(Undecked.dataPath, 'custom_integrations'), function (err) {
            if (err)
                throw err;
            _this.loadIntegrations(callback);
        });
    };
    IntegrationsManager.prototype.loadIntegrations = function (callback) {
        var instance = this;
        var integrations = { buildin: [], custom: [] };
        readdir(path.join(__filename, '..', 'buildin'), function (err, buildinfiles) {
            if (err)
                throw err;
            integrations.buildin = buildinfiles;
            readdir(path.join(Undecked.dataPath, 'custom_integrations'), function (err, customfiles) {
                if (err)
                    throw err;
                integrations.custom = customfiles;
                var loaded = { buildin: 0, custom: 0 };
                function loadIntegrations(type, cb, i) {
                    if (i === void 0) { i = 0; }
                    if (integrations[type][i]) {
                        var integrationID = integrations[type][i];
                        var integrationAddress = type == 'buildin'
                            ? path.join(__filename, '..', 'buildin', integrationID, 'integration')
                            : path.join(Undecked.dataPath, 'custom_integrations', integrationID, 'integration');
                        var waitInterval;
                        try {
                            instance.integrations[integrationID] = {
                                type: type,
                                api: null,
                                connectionslist: [],
                                connectionsmap: {},
                                integration: require(integrationAddress)
                            };
                            var waitCounter = 0;
                            waitInterval = setInterval(function () {
                                if (instance.integrations[integrationID].integration != undefined &&
                                    instance.integrations[integrationID].integration.main != undefined) {
                                    clearInterval(waitInterval);
                                    loaded[type]++;
                                    loadIntegrations(type, function () {
                                        (0, Logger_1.Log)('info', "Loaded ".concat(type, " integration '").concat(integrationID, "'"));
                                        cb();
                                    }, i + 1);
                                }
                                else {
                                    waitCounter++;
                                    if (waitCounter > 200) {
                                        clearInterval(waitInterval);
                                        delete instance.integrations[integrationID];
                                        (0, Logger_1.Log)('error', "Unable to load ".concat(type, " integration '").concat(integrationID, "': Loading timeout"));
                                        loadIntegrations(type, cb, i + 1);
                                    }
                                }
                            }, 10);
                        }
                        catch (error) {
                            clearInterval(waitInterval);
                            (0, Logger_1.Log)('error', "Unable to load ".concat(type, " integration '").concat(integrationID, "': ").concat(error.message));
                            loadIntegrations(type, cb, i + 1);
                        }
                    }
                    else
                        cb();
                }
                loadIntegrations('buildin', function () {
                    loadIntegrations('custom', function () {
                        for (var integrationID in instance.integrations) {
                            var integration = instance.integrations[integrationID];
                            // for (let i = 0; i < integration.integration.actions.length; i++) {
                            // 	if (integration.integration.actions[i] != undefined)
                            // 		integration.actionslist.push(integration.integration.actions[i].id);
                            // 	else
                            // 		Log(
                            // 			`warn`,
                            // 			`Invalid action of ${integrationID} ${JSON.stringify(
                            // 				integration.integration.actions[i],
                            // 				null,
                            // 				4
                            // 			)}`
                            // 		);
                            // }
                            if (integration.integration.connections != undefined)
                                for (var i = 0; i < integration.integration.connections.length; i++) {
                                    integration.connectionslist.push(integration.integration.connections[i].type);
                                    integration.connectionsmap[integration.integration.connections[i].type] =
                                        integration.integration.connections[i];
                                }
                            integration.api = new IntegrationApi_1.IntegrationAPI({ integrationID: integrationID, integration: integration });
                            try {
                                integration.integration.main(integration.api);
                            }
                            catch (error) {
                                (0, Logger_1.Log)('error', "Error in '".concat(integrationID, "'"), error.message, error.stack);
                            }
                        }
                        (0, Logger_1.Log)('info', "Loaded ".concat(loaded.buildin, " buildin integrations and ").concat(loaded.custom, " integrations"));
                        callback();
                    });
                });
            });
        });
    };
    IntegrationsManager.prototype.exists = function (integrationID) {
        return this.integrations[integrationID] != undefined;
    };
    IntegrationsManager.prototype.get = function (integrationID) {
        if (this.exists(integrationID))
            return this.integrations[integrationID];
        return null;
    };
    IntegrationsManager.prototype.getActions = function () {
        var actions = [];
        for (var integrationID in this.integrations) {
            var integration = this.integrations[integrationID];
            actions = actions.concat(integration.api.getActionList().map(function (action) {
                return {
                    integrationID: integrationID,
                    integrationName: integration.integration.name,
                    actionID: action.id,
                    actionName: action.name
                };
            }));
        }
        return actions;
    };
    IntegrationsManager.prototype.getConnections = function () {
        var connections = [];
        for (var integrationID in this.integrations) {
            var integration = this.integrations[integrationID];
            if (integration.integration.connections != undefined)
                for (var i = 0; i < integration.integration.connections.length; i++) {
                    var con = integration.integration.connections[i];
                    connections.push({
                        integrationID: integrationID,
                        integrationName: integration.integration.name,
                        connectionType: con.type,
                        connectionName: con.name
                    });
                }
        }
        connections.sort(function (a, b) {
            if (a.integrationName == b.integrationName)
                return 0;
            return a.integrationName > b.integrationName ? 1 : -1;
        });
        return connections;
    };
    IntegrationsManager.prototype.startEditor = function (settings) {
        var _this = this;
        if (this.exists(settings.integrationID)) {
            var integrationWrapper = this.get(settings.integrationID);
            var integration = integrationWrapper.integration;
            var integrationAPI = integrationWrapper.api;
            if (integrationAPI.hasAction(settings.actionID)) {
                var action = integrationAPI.getAction(settings.actionID);
                if (Undecked.Pages.exists(settings.pageID)) {
                    var page = Undecked.Pages.get(settings.pageID);
                    if (page.hasKey(settings.keyX, settings.keyY)) {
                        var key = page.getKey(settings.keyX, settings.keyY);
                        var actionInstance = page.getActionInstance(key, settings.actionInstanceID);
                        if (actionInstance) {
                            var editorID = Undecked.generateRandom(8, function (generatedValid) {
                                return !_this.exists(generatedValid);
                            });
                            var editorAPI = new EditorAPI_1.EditorAPI({
                                actionInstance: actionInstance,
                                integrationID: settings.integrationID,
                                pageID: settings.pageID,
                                editorID: editorID,
                                x: settings.keyX,
                                y: settings.keyY,
                                key: key
                            });
                            this.openEditors[editorID] = {
                                editor: editorAPI,
                                editorID: editorID,
                                ready: function () {
                                    editorAPI.isOpen = true;
                                    action._openEditor(editorAPI, actionInstance.properties);
                                },
                                destroy: function () {
                                    if (_this.openEditors[editorID] != undefined) {
                                        _this.openEditors[editorID].editor.close();
                                        delete _this.openEditors[editorID];
                                    }
                                }
                            };
                            return { actionEditorID: editorID, properties: {} };
                        }
                        else
                            return { error: "Key does not have this actioninstance" };
                    }
                    else
                        return { error: "Key does not exist" };
                }
                else
                    return { error: "Page '".concat(settings.pageID, "' does not exist") };
            }
            else
                return { error: "Action '".concat(settings.actionID, "' does not exist") };
        }
        else
            return { error: "Integration '".concat(settings.integrationID, "' does not exist") };
    };
    IntegrationsManager.prototype.editorExists = function (editorID) {
        return this.openEditors[editorID] != undefined;
    };
    IntegrationsManager.prototype.getEditor = function (editorID) {
        if (this.editorExists(editorID))
            return this.openEditors[editorID];
        return null;
    };
    IntegrationsManager.prototype.executeActions = function (actions, deck) {
        for (var actionInstanceID in actions) {
            var actionInstance = actions[actionInstanceID];
            if (Undecked.Integrations.exists(actionInstance.integrationID)) {
                var integration = Undecked.Integrations.get(actionInstance.integrationID);
                if (integration.api.hasAction(actionInstance.actionID)) {
                    var action = integration.api.getAction(actionInstance.actionID);
                    if (typeof action._hdl == 'function')
                        action._hdl(actionInstance.properties, function (text, type) {
                            if (type === void 0) { type = 'info'; }
                            if (actionInstance.logs == undefined)
                                actionInstance.logs = [];
                            actionInstance.logs = __spreadArray([
                                { timestamp: Date.now(), type: type, text: text }
                            ], actionInstance.logs, true);
                            if (actionInstance.logs.length > 20)
                                actionInstance.logs.splice(20, actionInstance.logs.length - 20);
                            // Log(
                            // 	<any>type.replace('warning', 'warn'),
                            // 	`[Deck:${deck != null ? deck.getName() : 'Internal'}][Integration:${integration
                            // 		.integration.name}][Action:${actionInstance.actionID}] ${text}`
                            // );
                        }, deck);
                    else
                        (0, Logger_1.Log)('warn', "Tried calling non-exisintg handler for action '".concat(actionInstance.actionID, "' of integration '").concat(actionInstance.integrationID, "'"));
                }
            }
        }
    };
    return IntegrationsManager;
}());
exports.IntegrationsManager = IntegrationsManager;
//# sourceMappingURL=IntegrationsManager.js.map