Object.defineProperty(exports, "__esModule", { value: true });
exports.ConnectionManager = void 0;
var path = require("path");
var fs_1 = require("fs");
var Logger_1 = require("./Logger");
var fs = require("fs-extra");
var ensureDir = fs.ensureDir, pathExists = fs.pathExists, readJson = fs.readJson;
var ConnectionManager = /** @class */ (function () {
    function ConnectionManager() {
    }
    ConnectionManager.prototype.load = function (callback) {
        var _this_1 = this;
        this.managerConfigPath = path.join(Undecked.dataPath, 'connections.json');
        this.connections = {};
        this.loadConfig(function () {
            var integration_count = 0;
            var device_count = 0;
            for (var integrationID in _this_1.connections) {
                integration_count++;
                device_count = device_count + Object.keys(_this_1.connections[integrationID]).length;
            }
            (0, Logger_1.Log)('info', "Loaded ".concat(device_count, " device(s) across ").concat(integration_count, " integration(s)"));
            callback();
        });
    };
    ConnectionManager.prototype.loadConfig = function (callback) {
        var _this_1 = this;
        pathExists(this.managerConfigPath, function (err, exists) {
            if (err)
                throw err;
            if (exists) {
                readJson(_this_1.managerConfigPath, function (err, json) {
                    if (err)
                        throw err;
                    _this_1.connections = json.connections;
                    for (var integrationID in _this_1.connections)
                        for (var connectionType in _this_1.connections[integrationID])
                            for (var connectionID in _this_1.connections[integrationID][connectionType]) {
                                var connection = _this_1.connections[integrationID][connectionType][connectionID];
                                _this_1.validate(integrationID, connectionType, connectionID, connection.properties, function (valid, error) {
                                    (0, Logger_1.Log)(valid ? 'info' : 'warn', valid
                                        ? "Loaded ".concat(connectionType, " '").concat(connection.name, "' from '").concat(integrationID, "'")
                                        : "Unable to load ".concat(connectionType, " '").concat(connection.name, "' from '").concat(integrationID, "'"));
                                });
                            }
                    callback();
                });
            }
            else {
                _this_1.connections = defaultConnectionConfig.connections;
                _this_1.saveConfig(callback);
            }
        });
    };
    ConnectionManager.prototype.saveConfig = function (callback) {
        var connections = {};
        for (var integrationID in this.connections) {
            connections[integrationID] = {};
            for (var connectionType in this.connections[integrationID]) {
                connections[integrationID][connectionType] = {};
                for (var connectionID in this.connections[integrationID][connectionType]) {
                    connections[integrationID][connectionType][connectionID] = this.connections[integrationID][connectionType][connectionID];
                    if (connections[integrationID][connectionType][connectionID].instance != undefined)
                        delete connections[integrationID][connectionType][connectionID].instance;
                }
            }
        }
        var toSave = {
            connections: connections
        };
        for (var integrationID in toSave.connections)
            for (var connectionType in toSave.connections[integrationID])
                for (var connectionID in toSave.connections[integrationID][connectionType])
                    if (toSave.connections[integrationID][connectionType][connectionID].instance != undefined)
                        delete toSave.connections[integrationID][connectionType][connectionID].instance;
        (0, fs_1.writeFile)(this.managerConfigPath, JSON.stringify(toSave, null, 4), function (err) {
            if (err)
                (0, Logger_1.Log)('error', 'Error whilst saving device manager config', err.message);
            if (callback)
                callback();
        });
    };
    ConnectionManager.prototype.create = function (integrationID, connectionType, properties, callback) {
        var _this_1 = this;
        var _this = this;
        if (this.connections == undefined)
            this.connections = {};
        if (this.connections[integrationID] == undefined)
            this.connections[integrationID] = {};
        if (this.connections[integrationID][connectionType] == undefined)
            this.connections[integrationID][connectionType] = {};
        var connectionID = Undecked.generateRandom(8, function (checkValid) {
            return _this.connections[integrationID][connectionType][checkValid] == undefined;
        });
        this.validate(integrationID, connectionType, connectionID, properties, function (valid, error) {
            if (valid == true) {
                var name = properties._internal_name;
                delete properties._internal_name;
                var instance = _this.connections[integrationID][connectionType] != undefined &&
                    _this.connections[integrationID][connectionType][connectionID] != undefined &&
                    _this.connections[integrationID][connectionType][connectionID].instance != undefined
                    ? _this.connections[integrationID][connectionType][connectionID].instance
                    : null;
                _this.connections[integrationID][connectionType][connectionID] = {
                    connectedSince: Date.now(),
                    lastSeen: Date.now(),
                    connectionID: connectionID,
                    name: name,
                    online: true,
                    properties: properties,
                    instance: instance
                };
                Undecked.SocketServer.broadcastTo('home', 'connectedlist', _this_1.getList());
                _this.saveConfig();
                callback(true);
            }
            else
                callback(false, error);
        });
    };
    ConnectionManager.prototype.validate = function (integrationID, connectionType, connectionID, properties, callback) {
        var _this = this;
        if (Undecked.Integrations.exists(integrationID)) {
            var integration = Undecked.Integrations.get(integrationID);
            if (integration.api.hasValidator(connectionType)) {
                var validator = integration.api.getValidator(connectionType);
                var connectionValidatorAPI = {
                    properties: properties,
                    callback: callback,
                    instance: _this.getConnectionInstance(integrationID, connectionType, connectionID),
                    setInstance: function (instance) {
                        _this.setConnectionInstance(integrationID, connectionType, connectionID, instance);
                    }
                };
                validator(connectionValidatorAPI);
            }
            else
                callback(false, "No validator found for connection type ".concat(connectionType));
        }
    };
    ConnectionManager.prototype.getConnectionRequestData = function (integrationID, connectionType) {
        if (Undecked.Integrations.exists(integrationID)) {
            var integrationwrapper = Undecked.Integrations.get(integrationID);
            if (integrationwrapper.integration.connections != undefined) {
                for (var i = 0; i < integrationwrapper.integration.connections.length; i++) {
                    var connection = integrationwrapper.integration.connections[i];
                    if (connection.type == connectionType)
                        return { fields: connection.fields, message: connection.message, link: connection.link };
                }
            }
        }
        return null;
    };
    ConnectionManager.prototype.getList = function () {
        var list = [];
        for (var integrationID in this.connections) {
            if (Undecked.Integrations.exists(integrationID)) {
                var integration = Undecked.Integrations.get(integrationID);
                for (var connectionType in this.connections[integrationID]) {
                    for (var connectionID in this.connections[integrationID][connectionType]) {
                        var connection = this.connections[integrationID][connectionType][connectionID];
                        list.push({
                            connectionID: connectionID,
                            integrationName: integration.integration.name,
                            connectionType: integration.connectionsmap[connectionType].name,
                            name: connection.name,
                            online: connection.online
                        });
                    }
                }
            }
        }
        return list;
    };
    ConnectionManager.prototype.getConnections = function (integrationID, connectionType) {
        var connections = [];
        if (this.connections != undefined) {
            if (this.connections[integrationID] != undefined) {
                if (this.connections[integrationID][connectionType] != undefined) {
                    for (var connectionID in this.connections[integrationID][connectionType]) {
                        var connection = this.connections[integrationID][connectionType][connectionID];
                        connections.push({ id: connection.connectionID, text: connection.name });
                    }
                }
            }
        }
        return connections;
    };
    ConnectionManager.prototype.getConnection = function (integrationID, connectionType, connectionID) {
        if (this.connections != undefined) {
            if (this.connections[integrationID] != undefined) {
                if (this.connections[integrationID][connectionType] != undefined) {
                    if (this.connections[integrationID][connectionType][connectionID] != undefined) {
                        return this.connections[integrationID][connectionType][connectionID];
                    }
                }
            }
        }
        return null;
    };
    ConnectionManager.prototype.setConnectionInstance = function (integrationID, connectionType, connectionID, instance) {
        if (this.connections == undefined)
            this.connections = {};
        if (this.connections[integrationID] == undefined)
            this.connections[integrationID] = {};
        if (this.connections[integrationID][connectionType] == undefined)
            this.connections[integrationID][connectionType] = {};
        if (this.connections[integrationID][connectionType][connectionID] == undefined)
            this.connections[integrationID][connectionType][connectionID] = {};
        this.connections[integrationID][connectionType][connectionID].instance = instance;
        return true;
    };
    ConnectionManager.prototype.getConnectionInstance = function (integrationID, connectionType, connectionID) {
        if (this.connections != undefined) {
            if (this.connections[integrationID] != undefined) {
                if (this.connections[integrationID][connectionType] != undefined) {
                    if (this.connections[integrationID][connectionType][connectionID] != undefined) {
                        return this.connections[integrationID][connectionType][connectionID].instance;
                    }
                }
            }
        }
        return null;
    };
    return ConnectionManager;
}());
exports.ConnectionManager = ConnectionManager;
var defaultConnectionConfig = {
    connections: {}
};
//# sourceMappingURL=ConnectionManager.js.map