text: var chalk = require('chalk');
  var Q = require('q');
  var promptly = require('promptly');
  var createError = require('../util/createError');
  
  function JsonRenderer() {
      this._nrLogs = 0;
  }
  
  JsonRenderer.prototype.end = function(data) {
      if (this._nrLogs) {
          process.stderr.write(']\n');
      }
  
      if (data) {
          process.stdout.write(this._stringify(data) + '\n');
      }
  };
  
  JsonRenderer.prototype.error = function(err) {
      var message = err.message;
      var stack;
  
      err.id = err.code || 'error';
      err.level = 'error';
      err.data = err.data || {};
  
      // Need to set message again because it is
      // not enumerable in some cases
      delete err.message;
      err.message = message;
  
      // Stack
      stack = err.fstream_stack || err.stack || 'N/A';
      err.stacktrace = Array.isArray(stack) ? stack.join('\n') : stack;
  
      this.log(err);
      this.end();
  };
  
  JsonRenderer.prototype.log = function(log) {
      if (!this._nrLogs) {
          process.stderr.write('[');
      } else {
          process.stderr.write(', ');
      }
  
      process.stderr.write(this._stringify(log));
      this._nrLogs++;
  };
  
  JsonRenderer.prototype.prompt = function(prompts) {
      var promise = Q.resolve();
      var answers = {};
      var that = this;
  
      prompts.forEach(function(prompt) {
          var opts;
          var funcName;
  
          // Strip colors
          prompt.message = chalk.stripColor(prompt.message);
  
          // Prompt
          opts = {
              silent: true, // To not mess with JSON output
              trim: false, // To allow " " to not assume the default value
              default: prompt.default == null ? '' : prompt.default, // If default is null, make it '' so that it does not retry
              validator: !prompt.validate
                  ? null
                  : function(value) {
                        var ret = prompt.validate(value);
  
                        if (typeof ret === 'string') {
                            throw ret;
                        }
  
                        return value;
                    }
          };
  
          // For now only "input", "confirm" and "password" are supported
          switch (prompt.type) {
              case 'input':
                  funcName = 'prompt';
                  break;
              case 'confirm':
              case 'password':
                  funcName = prompt.type;
                  break;
              case 'checkbox':
                  funcName = 'prompt';
                  break;
              default:
                  promise = promise.then(function() {
                      throw createError('Unknown prompt type', 'ENOTSUP');
                  });
                  return;
          }
  
          promise = promise.then(function() {
              // Log
              prompt.level = 'prompt';
              that.log(prompt);
  
              return Q.nfcall(promptly[funcName], '', opts).then(function(
                  answer
              ) {
                  answers[prompt.name] = answer;
              });
          });
  
          if (prompt.type === 'checkbox') {
              promise = promise.then(function() {
                  answers[prompt.name] = answers[prompt.name].split(',');
              });
          }
      });
  
      return promise.then(function() {
          return answers;
      });
  };
  
  // -------------------------
  
  JsonRenderer.prototype._stringify = function(log) {
      // To json
      var str = JSON.stringify(log, null, '  ');
      // Remove colors in case some log has colors..
      str = chalk.stripColor(str);
  
      return str;
  };
  
  module.exports = JsonRenderer;
  