static alias_Vector(struct engine_Command *) _command_all = ALIAS_VECTOR_INIT;
static alias_Vector(uint32_t) _command_by_name = ALIAS_VECTOR_INIT;

static int _command_by_name_compare(const void *ap, const void *bp, void *ud) {
  uint32_t a = *(uint32_t *)ap;
  uint32_t b = *(uint32_t *)bp;
  return strcmp(_command_all.data[a]->name, _command_all.data[b]->name);
}

static struct engine_Command ** _command_find(const char * name) {
  if(_command_all.length == 0) {
    return NULL;
  }
  struct engine_Command _search_command = {.name = name};
  uint32_t key = _command_all.length;
  _command_all.data[key] = &_search_command;
  uint32_t *found = bsearch(&key, _command_by_name.data, _command_by_name.length, sizeof(*_command_by_name.data), _command_by_name_compare, NULL);
  if(found == NULL) {
    return NULL;
  }
  return &_command_all.data[*found];
}

static void _command_insert(struct engine_Command *cmd) {
  uint32_t index = _command_all.length;

  alias_Vector_space_for(&_command_all, NULL, 2);
  alias_Vector_space_for(&_command_by_name, NULL, 2);

  *alias_Vector_push(&_command_all) = cmd;
  *alias_Vector_push(&_command_by_name) = index;

  qsort(_command_by_name.data, _command_by_name.length, sizeof(*_command_by_name.data), _command_by_name_compare, NULL);
}

void engine_command_register(struct engine_Command * cmd) {
  struct engine_Command **cmd_ptr = _command_find(cmd->name);
  if(cmd_ptr != NULL) {
    engine_error("attempting to register multiple commands with the same name: %s", cmd->name);
    return;
  }
  _command_insert(cmd);
}

static void _command_execute(int argc, char const * const * argv) {
  struct engine_Command **cmd_ptr = _command_find(argv[0]);
  if(cmd_ptr == NULL) {
    engine_error("unknown command %s", argv[0]);
    return;
  }
  (*cmd_ptr)->f(argc, argv);
}