/* --------------------------------------------------------------------------------------------
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See License.txt in the project root for license information.
 * ------------------------------------------------------------------------------------------ */
'use strict';
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 __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result["default"] = mod;
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const net = __importStar(require("net"));
const coc_nvim_1 = require("coc.nvim");
const coc_nvim_2 = require("coc.nvim");
const utils_1 = require("./utils");
const platform_1 = require("./platform");
const settings = require("./settings");
const process = __importStar(require("./process"));
const messages_1 = require("./messages");
function getSelectedTextToExecute(mode) {
    return __awaiter(this, void 0, void 0, function* () {
        let doc = coc_nvim_1.workspace.getDocument(coc_nvim_1.workspace.bufnr);
        if (!doc)
            return "";
        if (mode === 'n') {
            // get whole line.
            let range = yield coc_nvim_1.workspace.getCursorPosition();
            if (range)
                return doc.getline(range.line);
        }
        else {
            let range = yield coc_nvim_1.workspace.getSelectedRange(mode, doc);
            if (range)
                return doc.textDocument.getText(range);
        }
        return "";
    });
}
function startREPLProc(context, config, pwshPath, title) {
    return () => __awaiter(this, void 0, void 0, function* () {
        let proc = new process.PowerShellProcess(config, pwshPath, title);
        let sessionDetails = yield proc.start();
        let socket = net.connect(sessionDetails.languageServicePipeName);
        let streamInfo = () => new Promise((resolve, __) => {
            socket.on("connect", () => {
                proc.log.appendLine("Language service connected.");
                resolve({ writer: socket, reader: socket });
            });
        });
        // Options to control the language client
        let clientOptions = {
            // Register the server for powershell documents
            documentSelector: [{ scheme: 'file', language: 'ps1' }],
            synchronize: {
                // Synchronize the setting section 'powershell' to the server
                configurationSection: 'powershell',
                // Notify the server about file changes to PowerShell files contain in the workspace
                fileEvents: [
                    coc_nvim_1.workspace.createFileSystemWatcher('**/*.ps1'),
                    coc_nvim_1.workspace.createFileSystemWatcher('**/*.psd1'),
                    coc_nvim_1.workspace.createFileSystemWatcher('**/*.psm1')
                ]
            }
        };
        // Create the language client and start the client.
        let client = new coc_nvim_2.LanguageClient('ps1', 'PowerShell Language Server', streamInfo, clientOptions);
        let disposable = client.start();
        let doEval = function (mode) {
            return __awaiter(this, void 0, void 0, function* () {
                let document = yield coc_nvim_1.workspace.document;
                if (!document || document.filetype !== 'ps1') {
                    return;
                }
                const content = yield getSelectedTextToExecute(mode);
                const evaluateArgs = {
                    expression: content,
                };
                client.sendRequest(messages_1.EvaluateRequestMessage, evaluateArgs);
                yield proc.showTerminalIfNotVisible();
            });
        };
        let cmdShowTerminal = coc_nvim_1.commands.registerCommand("powershell.showTerminal", () => __awaiter(this, void 0, void 0, function* () { return proc.showTerminal(); }));
        let cmdHideTerminal = coc_nvim_1.commands.registerCommand("powershell.hideTerminal", () => __awaiter(this, void 0, void 0, function* () { return proc.hideTerminal(); }));
        let cmdToggleTerminal = coc_nvim_1.commands.registerCommand("powershell.toggleTerminal", () => __awaiter(this, void 0, void 0, function* () { return proc.toggleTerminal(); }));
        let cmdEvalLine = coc_nvim_1.commands.registerCommand("powershell.evaluateLine", () => __awaiter(this, void 0, void 0, function* () { return doEval('n'); }));
        let cmdEvalSelection = coc_nvim_1.commands.registerCommand("powershell.evaluateSelection", () => __awaiter(this, void 0, void 0, function* () { return doEval('v'); }));
        let cmdExecFile = coc_nvim_1.commands.registerCommand("powershell.execute", (...args) => __awaiter(this, void 0, void 0, function* () {
            let document = yield coc_nvim_1.workspace.document;
            if (!document || document.filetype !== 'ps1') {
                return;
            }
            if (document.schema === "untitled") {
                coc_nvim_1.workspace.showMessage("Can't run file because it's an in-memory file. Save the contents to a file and try again.", 'error');
                return;
            }
            let argStrs = args
                ? args.map(x => `${x}`)
                : [];
            let filePath = utils_1.fileURLToPath(document.uri);
            proc.log.appendLine(`executing: ${filePath}`);
            // Escape single quotes by adding a second single quote.
            if (filePath.indexOf('\'') !== -1) {
                filePath = filePath.replace(/'/, '\'\'');
            }
            // workaround until document.dirty works
            if (Number.parseInt(yield coc_nvim_1.workspace.nvim.commandOutput("echo &modified"))) {
                if (!(yield coc_nvim_1.workspace.showPrompt("Your file will be saved first before it runs. Is that ok?"))) {
                    return;
                }
                // workaround until document.textDocument.save() is supported.
                yield coc_nvim_1.workspace.nvim.command('w');
            }
            let exeChar = '&';
            if (config.integratedConsole.executeInCurrentScope) {
                exeChar = '.';
            }
            const evaluateArgs = {
                expression: `${exeChar} '${filePath}'`,
            };
            yield client.sendRequest(messages_1.EvaluateRequestMessage, evaluateArgs);
            yield proc.showTerminalIfNotVisible();
        }));
        // Push the disposable to the context's subscriptions so that the 
        // client can be deactivated on extension deactivation
        context.subscriptions.push(disposable, cmdExecFile, cmdEvalLine, cmdEvalSelection, cmdShowTerminal, cmdHideTerminal, cmdToggleTerminal);
        return proc.onExited;
    });
}
function activate(context) {
    return __awaiter(this, void 0, void 0, function* () {
        let config = settings.load();
        let pwshPath = config.powerShellExePath
            ? config.powerShellExePath
            : platform_1.getDefaultPowerShellPath(platform_1.getPlatformDetails());
        // Status bar entry showing PS version
        let versionBarItem = coc_nvim_1.workspace.createStatusBarItem(0, { progress: false });
        versionBarItem.text = pwshPath.indexOf("powershell.exe") >= 0
            ? "PS-Desktop"
            : "PS-Core";
        versionBarItem.show();
        coc_nvim_1.events.on('BufEnter', () => __awaiter(this, void 0, void 0, function* () {
            let document = yield coc_nvim_1.workspace.document;
            if (!document) {
                versionBarItem.hide();
                return;
            }
            if (document.filetype === 'ps1') {
                versionBarItem.show();
            }
            else {
                versionBarItem.hide();
            }
        }));
        let fnproc = startREPLProc(context, config, pwshPath, "PowerShell REPL");
        let daemon = function () {
            return __awaiter(this, void 0, void 0, function* () {
                let onExit = yield fnproc();
                onExit(() => __awaiter(this, void 0, void 0, function* () { yield daemon(); }));
            });
        };
        yield daemon();
    });
}
exports.activate = activate;
//# sourceMappingURL=extension.js.map