"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var wireProtocol_1 = require("./wireProtocol");
var logger_1 = require("../logger");
var callbackMap_1 = require("./callbackMap");
var utils_1 = require("../utils");
var TypeScriptServer = /** @class */ (function () {
    function TypeScriptServer(serverProcess) {
        var _this = this;
        this.serverProcess = serverProcess;
        this.callbacks = new callbackMap_1.CallbackMap();
        this.reader = new wireProtocol_1.Reader(this.serverProcess.stdout, function (msg) { return _this.handleMessage(msg); }, function (error) { return logger_1.log("Reader error: " + error); });
    }
    TypeScriptServer.prototype.initialize = function (reqId, rootUri) {
        return this.sendRequest(reqId, "initialize", {
            processId: process.pid,
            rootPath: utils_1.toPath(rootUri),
            rootUri: rootUri,
            initializationOptions: {},
            capabilities: { streaming: false }
        });
    };
    TypeScriptServer.prototype.kill = function () {
        this.serverProcess.kill();
    };
    TypeScriptServer.prototype.hover = function (reqId, fileUri, line, character) {
        return this.sendRequest(reqId, "textDocument/hover", {
            textDocument: { uri: fileUri },
            position: { line: line, character: character }
        });
    };
    TypeScriptServer.prototype.definition = function (reqId, fileUri, line, character) {
        return this.sendRequest(reqId, "textDocument/definition", {
            textDocument: { uri: fileUri },
            position: { line: line, character: character }
        });
    };
    TypeScriptServer.prototype.references = function (reqId, fileUri, line, character) {
        return this.sendRequest(reqId, "textDocument/references", {
            textDocument: { uri: fileUri },
            position: { line: line, character: character }
        });
    };
    TypeScriptServer.prototype.write = function (request) {
        // TODO: handle case when the pipe is closed (process crashed)
        var msg = JSON.stringify(request) + "\r\n";
        var chunk = "Content-Length: " + msg.length + "\r\n\r\n" + msg;
        logger_1.log("Writing to server: " + chunk);
        this.serverProcess.stdin.write(chunk, "utf8");
    };
    TypeScriptServer.prototype.sendRequest = function (requestId, method, params) {
        var _this = this;
        var request = {
            jsonrpc: "2.0",
            id: requestId,
            method: method,
            params: params
        };
        var result = new Promise(function (resolve, reject) {
            _this.callbacks.add(requestId, { onSuccess: resolve, onError: reject });
            _this.write(request);
        });
        return result;
    };
    TypeScriptServer.prototype.handleMessage = function (message) {
        // Can potentially handle `window/logMessage` type differently for logging
        logger_1.log("Server handleMessage: " + JSON.stringify(message));
        var messageId = message.id;
        var callback = this.callbacks.fetch(messageId);
        if (!callback) {
            return;
        }
        callback.onSuccess(message);
    };
    return TypeScriptServer;
}());
exports.TypeScriptServer = TypeScriptServer;
