module EacRubyUtils::Console::DocoptRunner::SubcommandsSupport

def auto_available_subcommands

def auto_available_subcommands
  self.class.constants
      .map { |name| self.class.const_get(name) }
      .select { |c| c.instance_of? Class }
      .select { |c| c < ::EacRubyUtils::Console::DocoptRunner }
      .map { |c| c.name.demodulize.underscore.dasherize }
end

def available_subcommands

def available_subcommands
  r = ::Set.new(setting_value(:subcommands, false) || auto_available_subcommands)
  if respond_to?(EXTRA_AVAILABLE_SUBCOMMANDS_METHOD_NAME, true)
    r += send(EXTRA_AVAILABLE_SUBCOMMANDS_METHOD_NAME)
  end
  r.sort
end

def check_subcommands_arg

def check_subcommands_arg
  if subcommand_arg_as_list?
    singleton_class.include(SubcommandsSupport::SubcommandArgAsList)
  else
    singleton_class.include(SubcommandsSupport::SubcommandArgAsArg)
  end
end

def check_valid_subcommand

def check_valid_subcommand
  return if available_subcommands.include?(subcommand_name)
  raise ::Docopt::Exit, "\"#{subcommand_name}\" is not a valid subcommand" \
    " (Valid: #{available_subcommands.join(', ')})"
end

def docopt_options

def docopt_options
  super.merge(options_first: true)
end

def run_with_subcommand

def run_with_subcommand
  if subcommand_name
    check_valid_subcommand
    subcommand.run
  else
    run_without_subcommand
  end
end

def run_without_subcommand

def run_without_subcommand
  "Method #{__method__} should be overrided in #{self.class.name}"
end

def subcommand

def subcommand
  @subcommand ||= subcommand_class_name(subcommand_name).constantize.create(
    argv: subcommand_args,
    program_name: subcommand_program,
    parent: self
  )
end

def subcommand_arg_as_list?

def subcommand_arg_as_list?
  setting_value(:subcommand_arg_as_list, false) || false
end

def subcommand_args

def subcommand_args
  options.fetch(SUBCOMMAND_ARGS_ARG)
end

def subcommand_class_name(subcommand)

def subcommand_class_name(subcommand)
  "#{self.class.name}::#{subcommand.underscore.camelize}"
end

def subcommand_program

def subcommand_program
  subcommand_name
end

def target_doc

def target_doc
  super.gsub(SUBCOMMANDS_MACRO,
             "#{target_doc_subcommand_arg} [#{SUBCOMMAND_ARGS_ARG}...]") +
    "\n" + subcommands_target_doc
end