/
bo_decl_members_begin(BHelpCmd, BCommand)
  /* injected */
  BConsoleLogger *logger;
bo_end();

/* BHelpCmd constructor parameters */
bo_decl_params_begin(BHelpCmd)
  BConsoleLogger *logger;
bo_end();

bo_impl_type(BHelpCmd, BCommand);

/* virtuals */
static const char *
name(BHelpCmd *self)
{
  be_assert(bo_is_typeof(self, BHelpCmd), "invalid command");
  return "help";
}

static be_exec_cmd_state_t
execute(BHelpCmd *self,
        int       argc,
        char     *argv[])
{
  be_assert(bo_is_typeof(self, BHelpCmd), "invalid command");

  BHashTable *cmds = be_console_logger_cmds(self->logger);
  if (!cmds)
    return BE_CMD_UNKNOWN;

  BCommand *cmd = NULL;

  be_iterator_t iter = be_htbl_begin(cmds);
  be_iterator_t end  = be_htbl_end(cmds);

  be_print("Available commands:");
  while (!be_iterator_equal(&iter, &end)) {
    cmd = be_htbl_iter_peek_value(cmds, &iter, BCommand *);

    be_print("  %s", bo_vtbl(cmd, BCommand)->name(cmd));
    be_htbl_iter_next(cmds, &iter);
  }

  return BE_CMD_SUCCESS;
}
/* virtuals */


/* BHelpCmd class init */
void
BHelpCmdKlass_init(BHelpCmdKlass *klass)
{
  bo_vtbl_cl(klass, BCommand)->name
    = (const char *(*)(BCommand *)) name;

  bo_vtbl_cl(klass, BCommand)->execute
    = (be_exec_cmd_state_t (*)(BCommand *, int, char *[])) execute;
}

/* BHelpCmd constructor */
void
BHelpCmd_ctor(BHelpCmd *self, BHelpCmdParams *p)
{
  be_assert(p, "invalid params");
  self->logger = p->logger;
}

/* BHelpCmd destructor */
void
BHelpCmd_dtor(BHelpCmd *self)
{
}

/* BHelpCmd copy constructor */
bo_copy_result
BHelpCmd_copy(BHelpCmd *self, BHelpCmd *other)
{
  return BO_NO_COPY;
}

/* public */
BHelpCmd *
be_help_cmd_new(BConsoleLogger *logger)
{
  BHelpCmdParams p = {
    .logger = logger
  };
  
  return bo_new(BHelpCmd, &p);
}

