"use strict";
var Future = require("fibers/future");
var prompt = require("inquirer");
var helpers = require("./helpers");
var readline = require("readline");
var MuteStream = require("mute-stream");
var Prompter = (function () {
    function Prompter() {
        this.muteStreamInstance = null;
    }
    Prompter.prototype.dispose = function () {
        if (this.ctrlcReader) {
            this.ctrlcReader.close();
        }
    };
    Prompter.prototype.get = function (schemas) {
        var _this = this;
        return (function () {
            try {
                _this.muteStdout();
                var future_1 = new Future;
                if (!helpers.isInteractive()) {
                    if (_.some(schemas, function (s) { return !s.default; })) {
                        future_1.throw(new Error("Console is not interactive and no default action specified."));
                    }
                    else {
                        var result_1 = {};
                        _.each(schemas, function (s) {
                            result_1[s.name] = s.default();
                        });
                        future_1.return(result_1);
                    }
                }
                else {
                    prompt.prompt(schemas, function (result) {
                        if (result) {
                            future_1.return(result);
                        }
                        else {
                            future_1.throw(new Error("Unable to get result from prompt: " + result));
                        }
                    });
                }
                return future_1.wait();
            }
            finally {
                _this.unmuteStdout();
            }
        }).future()();
    };
    Prompter.prototype.getPassword = function (prompt, options) {
        var _this = this;
        return (function () {
            var schema = {
                message: prompt,
                type: "password",
                name: "password",
                validate: function (value) {
                    var allowEmpty = options && options.allowEmpty;
                    return (!allowEmpty && !value) ? "Password must be non-empty" : true;
                }
            };
            var result = _this.get([schema]).wait();
            return result.password;
        }).future()();
    };
    Prompter.prototype.getString = function (prompt, options) {
        var _this = this;
        return (function () {
            var schema = {
                message: prompt,
                type: "input",
                name: "inputString",
                validate: function (value) {
                    var doesNotAllowEmpty = options && _.has(options, "allowEmpty") && !options.allowEmpty;
                    return (doesNotAllowEmpty && !value) ? prompt + " must be non-empty" : true;
                },
                default: options && options.defaultAction
            };
            var result = _this.get([schema]).wait();
            return result.inputString;
        }).future()();
    };
    Prompter.prototype.promptForChoice = function (promptMessage, choices) {
        var _this = this;
        return (function () {
            var schema = {
                message: promptMessage,
                type: "list",
                name: "userAnswer",
                choices: choices
            };
            var result = _this.get([schema]).wait();
            return result.userAnswer;
        }).future()();
    };
    Prompter.prototype.confirm = function (prompt, defaultAction) {
        var _this = this;
        return (function () {
            var schema = {
                type: "confirm",
                name: "prompt",
                default: defaultAction,
                message: prompt
            };
            var result = _this.get([schema]).wait();
            return result.prompt;
        }).future()();
    };
    Prompter.prototype.muteStdout = function () {
        if (helpers.isInteractive()) {
            process.stdin.setRawMode(true);
            this.muteStreamInstance = new MuteStream();
            this.muteStreamInstance.pipe(process.stdout);
            this.muteStreamInstance.mute();
            this.ctrlcReader = readline.createInterface({
                input: process.stdin,
                output: this.muteStreamInstance
            });
            this.ctrlcReader.on("SIGINT", process.exit);
        }
    };
    Prompter.prototype.unmuteStdout = function () {
        if (helpers.isInteractive()) {
            process.stdin.setRawMode(false);
            if (this.muteStreamInstance) {
                this.cleanEventListeners(process.stdout);
                this.muteStreamInstance.unmute();
                this.muteStreamInstance = null;
                this.dispose();
            }
        }
    };
    Prompter.prototype.cleanEventListeners = function (stream) {
        var _this = this;
        var memoryLeakEvents = [{
                eventName: "close",
                listenerName: "cleanup"
            }, {
                eventName: "error",
                listenerName: "onerror"
            }, {
                eventName: "drain",
                listenerName: "ondrain"
            }];
        _.each(memoryLeakEvents, function (memoryleakEvent) { return _this.cleanListener(stream, memoryleakEvent.eventName, memoryleakEvent.listenerName); });
    };
    Prompter.prototype.cleanListener = function (stream, eventName, listenerName) {
        var eventListeners = process.stdout.listeners(eventName);
        var listenerFunction = _.find(eventListeners, function (func) { return func.name === listenerName; });
        if (listenerFunction) {
            stream.removeListener(eventName, listenerFunction);
        }
    };
    return Prompter;
}());
exports.Prompter = Prompter;
$injector.register("prompter", Prompter);
