"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.SshService = void 0;
// import { simpleGit, ResetMode, SimpleGit } from 'simple-git'
var uid_1 = require("uid");
var fs = require("fs");
// import * as mkdirp from 'mkdirp'
var os = require("os");
var path = require("path");
// import moment = require("moment");
var ws_1 = require("ws");
var ssh2_1 = require("ssh2");
var utf8 = require("utf8");
var pty = require("node-pty");
var shell = os.platform() === 'win32' ? 'powershell.exe' : '/bin/zsh';
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 sshConnectionFilePath = path.resolve(appFolder, 'ssh.connection.json');
if (!fs.existsSync(sshConnectionFilePath)) {
    // console.log('创建目录')
    // fs.mkdirSync(yunserFolder)
    fs.writeFileSync(sshConnectionFilePath, '[]', 'utf8');
}
var commandDbFilePath = path.resolve(appFolder, 'ssh.command.json');
if (!fs.existsSync(commandDbFilePath)) {
    // console.log('创建目录')
    // fs.mkdirSync(yunserFolder)
    fs.writeFileSync(commandDbFilePath, '[]', 'utf8');
}
// let gitSettingFilePath = path.resolve(appFolder, 'git.settings.json')
// if (!fs.existsSync(gitSettingFilePath)) {
//     // console.log('创建目录')
//     // fs.mkdirSync(yunserFolder)
//     fs.writeFileSync(gitSettingFilePath, '{}', 'utf8')
// }
var folderPath = '/Users/yunser/app/dms-new';
var wss = new ws_1.WebSocket.Server({
    port: 10087
});
function createSocket(ws) {
    var ssh;
    var g_stream;
    function initSsh(config, ws) {
        var defaultPath = config.defaultPath, ptySize = config.ptySize;
        if (config && config.host) {
            var ssh_1 = new ssh2_1.Client();
            ssh_1
                .on("ready", function () {
                // ws.send("\r\n*** SSH CONNECTION ESTABLISHED ***\r\n");
                ssh_1.shell({ cols: ptySize.cols, rows: ptySize.rows }, function (err, stream) {
                    if (err) {
                        return ws.emit("\r\n*** SSH SHELL ERROR: " + err.message + " ***\r\n");
                    }
                    g_stream = stream;
                    g_stream.resize = function (cols, rows, width, height) {
                        stream.setWindow(rows, cols, width, height);
                    };
                    stream
                        .on("data", function (d) {
                        var data = utf8.decode(d.toString("binary"));
                        // ws.send(data)
                        ws.send(JSON.stringify({
                            type: 'res',
                            data: data,
                        }));
                    })
                        .on("close", function () {
                        //   ssh.end();
                    });
                });
            })
                .on("close", function () {
                ws.close();
            })
                .on("error", function (err) {
                console.log("\r\n*** SSH CONNECTION ERROR: " + err.message + " ***\r\n");
                ws.close();
            });
            ssh_1.connect({
                host: config.host,
                port: config.port,
                username: config.username,
                password: config.password,
            });
            return ssh_1;
        }
        else {
            var ptyProcess = pty.spawn(shell, [], {
                name: 'xterm-color',
                // cols: 80,
                // rows: 30,
                cols: ptySize.cols || 42,
                rows: ptySize.rows || 30,
                cwd: defaultPath || process.env.HOME,
                // cwd: '/Users/yunser/app/git-auto-2',
                env: process.env
            });
            // ptyProcess.resize()
            ptyProcess.on('data', function (data) {
                // console.log('ptyProcess', data)
                // process.stdout.write(data);
                ws.send(JSON.stringify({
                    type: 'res',
                    data: data,
                }));
            });
            // ptyProcess.write('ls\r');
            // ptyProcess.resize(100, 40);
            // ptyProcess.write('ls\r');
            g_stream = ptyProcess;
        }
    }
    ws.on("message", function (data) {
        console.log("websocket/on message", data.toString());
        var msg;
        try {
            msg = JSON.parse(data.toString());
        }
        catch (err) {
            // nothing
        }
        if (msg) {
            if (msg.type == 'connect') {
                ssh = initSsh(msg.data, ws);
            }
            else if (msg.type == 'command') {
                g_stream.write(msg.data);
            }
            else if (msg.type == 'resize') {
                var _a = msg.data, rows = _a.rows, cols = _a.cols, width = _a.width, height = _a.height;
                g_stream.resize(cols, rows, width, height);
            }
        }
        // 
    });
    ws.on("close", function () {
        console.log("websocket/close");
        ssh && ssh.end();
    });
}
wss.on("connection", function (ws) {
    console.log('websocket/connection');
    createSocket(ws);
});
var SshService = /** @class */ (function () {
    function SshService() {
    }
    SshService.prototype.home = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                return [2 /*return*/, 'ssh home'];
            });
        });
    };
    SshService.prototype.connect = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            function _connect() {
                return new Promise(function (resolve, reject) {
                    var ssh = new ssh2_1.Client();
                    ssh
                        .on("ready", function () {
                        resolve(null);
                    })
                        .on("error", function (err) {
                        reject(err);
                    });
                    ssh.connect({
                        host: body.host,
                        port: body.port,
                        username: body.username,
                        password: body.password,
                        readyTimeout: 4 * 1000,
                    });
                });
            }
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, _connect()];
                    case 1:
                        _a.sent();
                        return [2 /*return*/];
                }
            });
        });
    };
    SshService.prototype.connectionList = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var content;
            return __generator(this, function (_a) {
                content = fs.readFileSync(sshConnectionFilePath, 'utf-8');
                return [2 /*return*/, {
                        list: JSON.parse(content)
                    }];
            });
        });
    };
    SshService.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(sshConnectionFilePath, '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(sshConnectionFilePath, JSON.stringify(list, null, 4), 'utf-8');
                return [2 /*return*/, {}];
            });
        });
    };
    SshService.prototype.connectionCreate = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var content, list;
            return __generator(this, function (_a) {
                content = fs.readFileSync(sshConnectionFilePath, 'utf-8');
                list = JSON.parse(content);
                list.unshift(__assign(__assign({}, body), { id: (0, uid_1.uid)(32) }));
                fs.writeFileSync(sshConnectionFilePath, JSON.stringify(list, null, 4), 'utf-8');
                return [2 /*return*/, {}];
            });
        });
    };
    SshService.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(sshConnectionFilePath, '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(sshConnectionFilePath, JSON.stringify(newList, null, 4), 'utf-8');
                return [2 /*return*/, {}];
            });
        });
    };
    SshService.prototype.commandList = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var content;
            return __generator(this, function (_a) {
                content = fs.readFileSync(commandDbFilePath, 'utf-8');
                return [2 /*return*/, {
                        list: JSON.parse(content)
                    }];
            });
        });
    };
    return SshService;
}());
exports.SshService = SshService;
//# sourceMappingURL=ssh.service.js.map