text: "use strict";
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
      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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
          step((generator = generator.apply(thisArg, _arguments || [])).next());
      });
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  const prompt = require("inquirer");
  const helpers = require("./helpers");
  const readline = require("readline");
  const MuteStream = require("mute-stream");
  class Prompter {
      constructor() {
          this.descriptionSeparator = "|";
          this.muteStreamInstance = null;
      }
      dispose() {
          if (this.ctrlcReader) {
              this.ctrlcReader.close();
          }
      }
      get(questions) {
          return __awaiter(this, void 0, void 0, function* () {
              _.each(questions, q => {
                  q.filter = ((selection) => {
                      return selection.split(this.descriptionSeparator)[0].trim();
                  });
              });
              try {
                  this.muteStdout();
                  if (!helpers.isInteractive()) {
                      if (_.some(questions, s => !s.default)) {
                          throw new Error("Console is not interactive and no default action specified.");
                      }
                      else {
                          const result = {};
                          _.each(questions, s => {
                              result[s.name] = s.default();
                          });
                          return result;
                      }
                  }
                  else {
                      const result = yield prompt.prompt(questions);
                      return result;
                  }
              }
              finally {
                  this.unmuteStdout();
              }
          });
      }
      getPassword(message, options) {
          return __awaiter(this, void 0, void 0, function* () {
              const schema = {
                  message,
                  type: "password",
                  name: "password",
                  validate: (value) => {
                      const allowEmpty = options && options.allowEmpty;
                      return (!allowEmpty && !value) ? "Password must be non-empty" : true;
                  }
              };
              const result = yield this.get([schema]);
              return result.password;
          });
      }
      getString(message, options) {
          return __awaiter(this, void 0, void 0, function* () {
              const schema = {
                  message,
                  type: "input",
                  name: "inputString",
                  validate: (value) => {
                      const doesNotAllowEmpty = options && _.has(options, "allowEmpty") && !options.allowEmpty;
                      return (doesNotAllowEmpty && !value) ? `${message} must be non-empty` : true;
                  },
                  default: options && options.defaultAction
              };
              const result = yield this.get([schema]);
              return result.inputString;
          });
      }
      promptForChoice(promptMessage, choices) {
          return __awaiter(this, void 0, void 0, function* () {
              const schema = {
                  message: promptMessage,
                  type: "list",
                  name: "userAnswer",
                  choices: choices
              };
              const result = yield this.get([schema]);
              return result.userAnswer;
          });
      }
      promptForDetailedChoice(promptMessage, choices) {
          return __awaiter(this, void 0, void 0, function* () {
              const longestKeyLength = choices.concat().sort(function (a, b) { return b.key.length - a.key.length; })[0].key.length;
              const inquirerChoices = choices.map((choice) => {
                  return {
                      name: `${_.padEnd(choice.key, longestKeyLength)}  ${choice.description ? this.descriptionSeparator : ""}  ${choice.description}`,
                      short: choice.key
                  };
              });
              const schema = {
                  message: promptMessage,
                  type: "list",
                  name: "userAnswer",
                  choices: inquirerChoices
              };
              const result = yield this.get([schema]);
              return result.userAnswer;
          });
      }
      confirm(message, defaultAction) {
          return __awaiter(this, void 0, void 0, function* () {
              const schema = {
                  type: "confirm",
                  name: "prompt",
                  default: defaultAction,
                  message
              };
              const result = yield this.get([schema]);
              return result.prompt;
          });
      }
      muteStdout() {
          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);
          }
      }
      unmuteStdout() {
          if (helpers.isInteractive()) {
              process.stdin.setRawMode(false);
              if (this.muteStreamInstance) {
                  this.cleanEventListeners(process.stdout);
                  this.muteStreamInstance.unmute();
                  this.muteStreamInstance = null;
                  this.dispose();
              }
          }
      }
      cleanEventListeners(stream) {
          const memoryLeakEvents = [{
                  eventName: "close",
                  listenerName: "cleanup"
              }, {
                  eventName: "error",
                  listenerName: "onerror"
              }, {
                  eventName: "drain",
                  listenerName: "ondrain"
              }];
          _.each(memoryLeakEvents, (memoryleakEvent) => this.cleanListener(stream, memoryleakEvent.eventName, memoryleakEvent.listenerName));
      }
      cleanListener(stream, eventName, listenerName) {
          const eventListeners = process.stdout.listeners(eventName);
          const listenerFunction = _.find(eventListeners, (func) => func.name === listenerName);
          if (listenerFunction) {
              stream.removeListener(eventName, listenerFunction);
          }
      }
  }
  exports.Prompter = Prompter;
  $injector.register("prompter", Prompter);
  