text: /** internal
   * class ActionSubparsers
   *
   * Support the creation of such sub-commands with the addSubparsers()
   *
   * This class inherited from [[Action]]
   **/
  'use strict'
  
  var util = require('util')
  var format = require('util').format
  
  var Action = require('../action')
  
  // Constants
  var c = require('../const')
  
  // Errors
  var argumentErrorHelper = require('../argument/error')
  
  /*: nodoc:*
   * new ChoicesPseudoAction(name, help)
   *
   * Create pseudo action for correct help text
   *
   **/
  function ChoicesPseudoAction (name, help) {
    var options = {
      optionStrings: [],
      dest: name,
      help: help
    }
  
    Action.call(this, options)
  }
  
  util.inherits(ChoicesPseudoAction, Action)
  
  /**
   * new ActionSubparsers(options)
   * - options (object): options hash see [[Action.new]]
   *
   **/
  function ActionSubparsers (options) {
    options = options || {}
    options.dest = options.dest || c.SUPPRESS
    options.nargs = c.PARSER
  
    this.debug = (options.debug === true)
  
    this._progPrefix = options.prog
    this._parserClass = options.parserClass
    this._nameParserMap = {}
    this._choicesActions = []
  
    options.choices = this._nameParserMap
    Action.call(this, options)
  }
  
  util.inherits(ActionSubparsers, Action)
  
  /*: nodoc:*
   * ActionSubparsers#addParser(name, options) -> ArgumentParser
   * - name (string): sub-command name
   * - options (object): see [[ArgumentParser.new]]
   *
   *  Note:
   *  addParser supports an additional aliases option,
   *  which allows multiple strings to refer to the same subparser.
   *  This example, like svn, aliases co as a shorthand for checkout
   *
   **/
  ActionSubparsers.prototype.addParser = function (name, options) {
    var parser
  
    var self = this
  
    options = options || {}
  
    options.debug = (this.debug === true)
  
    // set program from the existing prefix
    if (!options.prog) {
      options.prog = this._progPrefix + ' ' + name
    }
  
    var aliases = options.aliases || []
  
    // create a pseudo-action to hold the choice help
    if (!!options.help || typeof options.help === 'string') {
      var help = options.help
      delete options.help
  
      var choiceAction = new ChoicesPseudoAction(name, help)
      this._choicesActions.push(choiceAction)
    }
  
    // create the parser and add it to the map
    parser = new this._parserClass(options)
    this._nameParserMap[name] = parser
  
    // make parser available under aliases also
    aliases.forEach(function (alias) {
      self._nameParserMap[alias] = parser
    })
  
    return parser
  }
  
  ActionSubparsers.prototype._getSubactions = function () {
    return this._choicesActions
  }
  
  /*: nodoc:*
   * ActionSubparsers#call(parser, namespace, values, optionString) -> Void
   * - parser (ArgumentParser): current parser
   * - namespace (Namespace): namespace for output data
   * - values (Array): parsed values
   * - optionString (Array): input option string(not parsed)
   *
   * Call the action. Parse input aguments
   **/
  ActionSubparsers.prototype.call = function (parser, namespace, values) {
    var parserName = values[0]
    var argStrings = values.slice(1)
  
    // set the parser name if requested
    if (this.dest !== c.SUPPRESS) {
      namespace[this.dest] = parserName
    }
  
    // select the parser
    if (this._nameParserMap[parserName]) {
      parser = this._nameParserMap[parserName]
    } else {
      throw argumentErrorHelper(format(
        'Unknown parser "%s" (choices: [%s]).',
        parserName,
        Object.keys(this._nameParserMap).join(', ')
      ))
    }
  
    // parse all the remaining options into the namespace
    parser.parseArgs(argStrings, namespace)
  }
  
  module.exports = ActionSubparsers
  