#include <mongoc.h>
#include <mongoc-client-private.h>


static void
print_doc (const bson_t *b)
{
   char *str;

   str = bson_as_json(b, NULL);
   MONGOC_DEBUG("%s", str);
   bson_free(str);
}


static void
ping (mongoc_database_t *db,
      const bson_t      *cmd)
{
   mongoc_cursor_t *cursor;
   const bson_t *b;
   bson_error_t error;

   cursor = mongoc_database_command(db, MONGOC_QUERY_NONE, 0, 1, 0, cmd, NULL, NULL);
   while (mongoc_cursor_next(cursor, &b)) {
      BSON_ASSERT(b);
      print_doc(b);
   }
   if (mongoc_cursor_error(cursor, &error)) {
      MONGOC_WARNING("Cursor error: %s", error.message);
   }
   mongoc_cursor_destroy(cursor);
}


static void
fetch (mongoc_collection_t *col,
       const bson_t        *spec)
{
   mongoc_cursor_t *cursor;
   const bson_t *b;
   bson_error_t error;

   cursor = mongoc_collection_find(col, MONGOC_QUERY_NONE, 0, 0, 0, spec, NULL, NULL);
   while (mongoc_cursor_next(cursor, &b)) {
      BSON_ASSERT(b);
      print_doc(b);
   }
   if (mongoc_cursor_error(cursor, &error)) {
      MONGOC_WARNING("Cursor error: %s", error.message);
   }
   mongoc_cursor_destroy(cursor);
}


static void
test_load (mongoc_client_t *client,
           unsigned         iterations)
{
   mongoc_collection_t *col;
   mongoc_database_t *db;
   bson_error_t error;
   unsigned i;
   bson_t b;
   bson_t q;

   bson_init(&b);
   bson_append_int32(&b, "ping", 4, 1);

   bson_init(&q);

   db = mongoc_client_get_database(client, "admin");
   col = mongoc_client_get_collection(client, "test", "test");

   for (i = 0; i < iterations; i++) {
      ping(db, &b);
      fetch(col, &q);
   }

   if (!mongoc_collection_drop(col, &error)) {
      MONGOC_WARNING("Failed to drop collection: %s", error.message);
   }

   mongoc_database_destroy(db);
   db = mongoc_client_get_database(client, "test");

   if (!mongoc_database_drop(db, &error)) {
      MONGOC_WARNING("Failed to drop database: %s", error.message);
   }

   mongoc_database_destroy(db);
   mongoc_collection_destroy(col);
   bson_destroy(&b);
}


int
main (int   argc,
      char *argv[])
{
   mongoc_client_pool_t *pool;
   mongoc_client_t *client;
   mongoc_uri_t *uri;
   unsigned count = 10000000;

   mongoc_init();

   if (argc > 1) {
      if (!(uri = mongoc_uri_new(argv[1]))) {
         fprintf(stderr, "Failed to parse uri: %s\n", argv[1]);
         return 1;
      }
   } else {
      uri = mongoc_uri_new("mongodb://127.0.0.1:27017/?sockettimeoutms=500");
   }

   if (argc > 2) {
      count = BSON_MAX(atoi(argv[2]), 1);
   }

   pool = mongoc_client_pool_new(uri);
   client = mongoc_client_pool_pop(pool);
   test_load(client, count);
   mongoc_client_pool_push(pool, client);
   mongoc_uri_destroy(uri);
   mongoc_client_pool_destroy(pool);

   mongoc_cleanup();

   return 0;
}
