"use strict";
/* --------------------------------------------------------------------------------------------
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See License.txt in the project root for license information.
 * ------------------------------------------------------------------------------------------ */
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());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const path = require("path");
const vscode = require("coc.nvim");
const utils = require("./utils");
const crypto = require("crypto");
class PowerShellProcess {
    constructor(config, pwshPath, title) {
        this.config = config;
        this.pwshPath = pwshPath;
        this.title = title;
        this.onExitedEmitter = new vscode.Emitter();
        this.consoleTerminal = undefined;
        this.log = vscode.workspace.createOutputChannel('powershell');
        this.cocPowerShellRoot = path.join(__dirname, "..", "..");
        this.bundledModulesPath = path.join(this.cocPowerShellRoot, "PowerShellEditorServices");
        this.onExited = this.onExitedEmitter.event;
    }
    static escapeSingleQuotes(pspath) {
        return pspath.replace(new RegExp("'", "g"), "''");
    }
    start() {
        return __awaiter(this, void 0, void 0, function* () {
            // If PowerShellEditorServices is not downloaded yet, run the install script to do so.
            if (!fs.existsSync(this.bundledModulesPath)) {
                const errMessage = "[Error] PowerShell Editor Services not found. Package is not in the correct format.";
                this.log.appendLine(errMessage);
                throw errMessage;
            }
            this.log.appendLine("starting.");
            this.log.appendLine(`pwshPath = ${this.pwshPath}`);
            this.log.appendLine(`bundledModulesPath = ${this.bundledModulesPath}`);
            let logDir = path.join(this.cocPowerShellRoot, `/.pses/logs/${crypto.randomBytes(16).toString("hex")}-${process.pid}`);
            this.sessionFilePath = path.join(logDir, "session");
            // Make sure no old session file exists
            utils.deleteSessionFile(this.sessionFilePath);
            let powerShellArgs = [];
            // Only add ExecutionPolicy param on Windows
            if (utils.isWindowsOS()) {
                powerShellArgs.push("-ExecutionPolicy", "Bypass");
            }
            powerShellArgs.push("-NoProfile", "-NonInteractive", path.join(this.bundledModulesPath, "/PowerShellEditorServices/Start-EditorServices.ps1"), "-HostName", "coc.vim", "-HostProfileId", "coc.vim", "-HostVersion", "2.0.0", "-LogPath", path.join(logDir, "log.txt"), "-LogLevel", this.config.developer.editorServicesLogLevel || "Normal", "-BundledModulesPath", this.bundledModulesPath, "-EnableConsoleRepl", "-SessionDetailsPath", this.sessionFilePath);
            this.consoleTerminal = yield vscode.workspace.createTerminal({
                name: this.title,
                shellPath: this.pwshPath,
                shellArgs: powerShellArgs
            });
            if (!this.config.integratedConsole.showOnStartup) {
                this.consoleTerminal.hide();
            }
            yield new Promise((resolve, reject) => {
                // Start the language client
                utils.waitForSessionFile(this.sessionFilePath, (sessionDetails, error) => {
                    // Clean up the session file
                    utils.deleteSessionFile(this.sessionFilePath);
                    if (error) {
                        reject(error);
                    }
                    else {
                        this.sessionDetails = sessionDetails;
                        resolve(this.sessionDetails);
                    }
                });
            });
            this.consoleCloseSubscription =
                vscode.workspace.onDidCloseTerminal((terminal) => {
                    if (terminal === this.consoleTerminal) {
                        this.log.appendLine("powershell.exe terminated or terminal UI was closed");
                        this.onExitedEmitter.fire();
                    }
                }, this);
            this.consoleTerminal.processId.then((pid) => { this.log.appendLine(`powershell.exe started, pid: ${pid}`); });
            return this.sessionDetails;
        });
    }
    showTerminalIfVisible() {
        return __awaiter(this, void 0, void 0, function* () {
            if (this.consoleTerminal) {
                const winid = yield vscode.workspace.nvim.eval(`bufwinid(${this.consoleTerminal.bufnr})`);
                // show terminal if hidded when running F5/F8
                if (winid == -1) {
                    this.consoleTerminal.show();
                }
                // this fill move cursor to consol after F5/F8
                if (this.config.integratedConsole.focusConsoleOnExecute) {
                    this.consoleTerminal.show();
                }
            }
        });
    }
    showTerminal() {
        return __awaiter(this, void 0, void 0, function* () { this.consoleTerminal.show(); });
    }
    hideTerminal() {
        return __awaiter(this, void 0, void 0, function* () { this.consoleTerminal.hide(); });
    }
    toggleTerminal() {
        return __awaiter(this, void 0, void 0, function* () {
            const winid = yield vscode.workspace.nvim.eval(`bufwinid(${this.consoleTerminal.bufnr})`);
            if (winid == -1) {
                this.consoleTerminal.show();
            }
            else {
                this.consoleTerminal.hide();
            }
        });
    }
    dispose() {
        // Clean up the session file
        utils.deleteSessionFile(this.sessionFilePath);
        if (this.consoleCloseSubscription) {
            this.consoleCloseSubscription.dispose();
            this.consoleCloseSubscription = undefined;
        }
        if (this.consoleTerminal) {
            this.log.appendLine("Terminating PowerShell process...");
            this.consoleTerminal.dispose();
            this.consoleTerminal = undefined;
        }
    }
}
exports.PowerShellProcess = PowerShellProcess;
//# sourceMappingURL=process.js.map