"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (g && (g = 0, op[0] && (_ = 0)), _) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MqttService = void 0;
var uid_1 = require("uid");
var fs = require("fs");
var path = require("path");
var mqtt = require("mqtt");
var ssh_service_1 = require("./ssh.service");
var clients = {};
var USER_HOME = process.env.HOME || process.env.USERPROFILE;
var yunserFolder = path.resolve(USER_HOME, '.yunser'); // TODO package，npm install cmd-core
if (!fs.existsSync(yunserFolder)) {
    // console.log('创建目录')
    fs.mkdirSync(yunserFolder);
}
var appFolder = path.resolve(yunserFolder, 'dms-cli'); // TODO package，npm install cmd-core
if (!fs.existsSync(appFolder)) {
    fs.mkdirSync(appFolder);
}
var redisConnectionFilePath = path.resolve(appFolder, 'mqtt.connection.json');
if (!fs.existsSync(redisConnectionFilePath)) {
    fs.writeFileSync(redisConnectionFilePath, '[]', 'utf8');
}
function mqttConnect(url, params) {
    console.log('mqttConnect', url, params);
    return new Promise(function (resolve, reject) {
        var client = mqtt.connect(url, __assign(__assign({}, params), { reconnectPeriod: 0, connectTimeout: 1000 }));
        client.on('connect', function () {
            console.log('mqttConnect/onConnect');
            resolve();
        });
        // client.on('message', function (topic, message) {
        //     // message is Buffer
        //     console.log('mqtt/on-message', topic, message.toString())
        //     sendMqttMsg({ topic, message: message.toString() })
        //   //   client.end()
        // })
        client.on('error', function (err) {
            // message is Buffer
            console.log('mqttConnect/on-error', err);
            //   client.end()
            reject(err);
        });
    });
}
var MqttService = /** @class */ (function () {
    function MqttService() {
    }
    MqttService.prototype.index = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                return [2 /*return*/, 'mqtt home'];
            });
        });
    };
    MqttService.prototype._getClient = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var connectionId;
            return __generator(this, function (_a) {
                connectionId = body.connectionId;
                return [2 /*return*/, clients[connectionId].client];
            });
        });
    };
    MqttService.prototype.publish = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var topic, message, client;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        topic = body.topic, message = body.message;
                        return [4 /*yield*/, this._getClient(body)];
                    case 1:
                        client = _a.sent();
                        client.publish(topic, message, {
                            qos: 1,
                        });
                        return [2 /*return*/, {}];
                }
            });
        });
    };
    MqttService.prototype.connect = function (config) {
        return __awaiter(this, void 0, void 0, function () {
            var connectionId, host, port, password, _a, test, userName, _b, clientId, url, params, client;
            return __generator(this, function (_c) {
                switch (_c.label) {
                    case 0:
                        connectionId = (0, uid_1.uid)(32);
                        host = config.host, port = config.port, password = config.password, _a = config.test, test = _a === void 0 ? false : _a, userName = config.userName, _b = config.clientId, clientId = _b === void 0 ? 'client-DMS' : _b;
                        url = "mqtt://".concat(host, ":").concat(port);
                        params = {
                            clientId: clientId,
                            username: userName,
                            password: password,
                        };
                        if (!test) return [3 /*break*/, 2];
                        return [4 /*yield*/, mqttConnect(url, params)];
                    case 1: return [2 /*return*/, _c.sent()];
                    case 2:
                        // const params = {
                        //     host,
                        //     port,
                        //     lazyConnect: true,
                        //     connectTimeout: 1000,
                        //     username: undefined,
                        //     password: undefined
                        //     // This is the default value of `retryStrategy`
                        //     // retryStrategy(times) {
                        //     //     const delay = Math.min(times * 50, 2000);
                        //     //     return delay;
                        //     // },
                        // }
                        // if (password) {
                        //     params.password = password
                        // }
                        // if (userName) {
                        //     params.username = userName 
                        // }
                        // console.log('params', params)
                        console.log('mqtt/connect');
                        client = mqtt.connect(url, params);
                        client.on('connect', function () {
                            console.log('mqtt/onConnect');
                            client.subscribe('msg/#', function (err) {
                                if (err) {
                                    console.log('mqtt/subscribe/error', err);
                                    return;
                                }
                                console.log('subscribe ok');
                                client.publish('msg/hello', 'Hello world! @DMS');
                                console.log('publish ok');
                            });
                        });
                        client.on('message', function (topic, message) {
                            // message is Buffer
                            console.log('mqtt/on-message', topic, message.toString());
                            (0, ssh_service_1.sendMqttMsg)({ topic: topic, message: message.toString() });
                            //   client.end()
                        });
                        client.on('error', function (err) {
                            // message is Buffer
                            console.log('mqtt/on-error', err);
                            //   client.end()
                        });
                        // if (test) {
                        //     // console.log('before connect')
                        //     try {
                        //         await g_redis.connect()
                        //     }
                        //     catch (err) {
                        //         console.log('err', err)
                        //     }
                        //     // console.log('after connect')
                        //     return {
                        //         ping: await g_redis.ping(),
                        //     }
                        // }
                        clients[connectionId] = {
                            client: client,
                            // params,
                        };
                        // try {
                        //     await g_redis.connect()
                        // }
                        // catch (err) {
                        //     console.log('err', err)
                        // }
                        // await g_redis.ping()
                        // await g_redis.connect()
                        // .catch(err2 => {
                        //     console.log('err2', err2.message, err2)
                        // })
                        // try {
                        // }
                        // catch (err) {
                        //     console.log('err', err.message, err)
                        // }
                        return [2 /*return*/, {
                                connectionId: connectionId,
                            }];
                }
            });
        });
    };
    MqttService.prototype.connectionList = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var content;
            return __generator(this, function (_a) {
                content = fs.readFileSync(redisConnectionFilePath, 'utf-8');
                return [2 /*return*/, {
                        list: JSON.parse(content)
                    }];
            });
        });
    };
    MqttService.prototype.connectionEdit = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var id, data, content, list, idx;
            return __generator(this, function (_a) {
                id = body.id, data = body.data;
                content = fs.readFileSync(redisConnectionFilePath, 'utf-8');
                list = JSON.parse(content);
                idx = list.findIndex(function (_item) { return _item.id == id; });
                list[idx] = __assign(__assign({}, list[idx]), data);
                console.log('list', list);
                fs.writeFileSync(redisConnectionFilePath, JSON.stringify(list, null, 4), 'utf-8');
                return [2 /*return*/, {}];
            });
        });
    };
    MqttService.prototype.connectionCreate = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var content, list;
            return __generator(this, function (_a) {
                content = fs.readFileSync(redisConnectionFilePath, 'utf-8');
                list = JSON.parse(content);
                list.unshift(__assign(__assign({}, body), { id: (0, uid_1.uid)(32) }));
                fs.writeFileSync(redisConnectionFilePath, JSON.stringify(list, null, 4), 'utf-8');
                return [2 /*return*/, {}];
            });
        });
    };
    MqttService.prototype.connectionDelete = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var id, content, list, newList;
            return __generator(this, function (_a) {
                id = body.id;
                content = fs.readFileSync(redisConnectionFilePath, 'utf-8');
                list = JSON.parse(content);
                newList = list.filter(function (item) { return item.id != id; });
                console.log('id', id);
                console.log('newList', newList);
                fs.writeFileSync(redisConnectionFilePath, JSON.stringify(newList, null, 4), 'utf-8');
                return [2 /*return*/, {}];
            });
        });
    };
    return MqttService;
}());
exports.MqttService = MqttService;
//# sourceMappingURL=mqtt.service.js.map