// example-manage-collection-indexes creates, lists and deletes an index from
// the `test.test` collection.

#include <mongoc/mongoc.h>
#include <stdlib.h> // abort

#define HANDLE_ERROR(...)                                                 \
   if (1) {                                                               \
      fprintf (stderr, "Failure at %s:%d\n", __FILE__, (int) (__LINE__)); \
      fprintf (stderr, __VA_ARGS__);                                      \
      fprintf (stderr, "\n");                                             \
      goto fail;                                                          \
   } else                                                                 \
      (void) 0

int
main (int argc, char *argv[])
{
   mongoc_client_t *client = NULL;
   const char *uri_string = "mongodb://127.0.0.1/?appname=create-indexes-example";
   mongoc_uri_t *uri = NULL;
   mongoc_collection_t *coll = NULL;
   bson_error_t error;
   bool ok = false;

   mongoc_init ();

   if (argc > 2) {
      HANDLE_ERROR ("Unexpected arguments. Expected usage: %s [CONNECTION_STRING]", argv[0]);
   }

   if (argc > 1) {
      uri_string = argv[1];
   }

   uri = mongoc_uri_new_with_error (uri_string, &error);
   if (!uri) {
      HANDLE_ERROR ("Failed to parse URI: %s", error.message);
   }
   client = mongoc_client_new_from_uri_with_error (uri, &error);
   if (!client) {
      HANDLE_ERROR ("Failed to create client: %s", error.message);
   }

   coll = mongoc_client_get_collection (client, "test", "test");

   {
      // Create an index ... begin
      // `keys` represents an ascending index on field `x`.
      bson_t *keys = BCON_NEW ("x", BCON_INT32 (1));
      mongoc_index_model_t *im = mongoc_index_model_new (keys, NULL /* opts */);
      if (mongoc_collection_create_indexes_with_opts (coll, &im, 1, NULL /* opts */, NULL /* reply */, &error)) {
         printf ("Successfully created index\n");
      } else {
         bson_destroy (keys);
         HANDLE_ERROR ("Failed to create index: %s", error.message);
      }
      bson_destroy (keys);
      // Create an index ... end
   }

   {
      // List indexes ... begin
      mongoc_cursor_t *cursor = mongoc_collection_find_indexes_with_opts (coll, NULL /* opts */);
      printf ("Listing indexes:\n");
      const bson_t *got;
      while (mongoc_cursor_next (cursor, &got)) {
         char *got_str = bson_as_canonical_extended_json (got, NULL);
         printf ("  %s\n", got_str);
         bson_free (got_str);
      }
      if (mongoc_cursor_error (cursor, &error)) {
         mongoc_cursor_destroy (cursor);
         HANDLE_ERROR ("Failed to list indexes: %s", error.message);
      }
      mongoc_cursor_destroy (cursor);
      // List indexes ... end
   }

   {
      // Drop an index ... begin
      bson_t *keys = BCON_NEW ("x", BCON_INT32 (1));
      char *index_name = mongoc_collection_keys_to_index_string (keys);
      if (mongoc_collection_drop_index_with_opts (coll, index_name, NULL /* opts */, &error)) {
         printf ("Successfully dropped index\n");
      } else {
         bson_free (index_name);
         bson_destroy (keys);
         HANDLE_ERROR ("Failed to drop index: %s", error.message);
      }
      bson_free (index_name);
      bson_destroy (keys);
      // Drop an index ... end
   }

   ok = true;
fail:
   mongoc_collection_destroy (coll);
   mongoc_client_destroy (client);
   mongoc_uri_destroy (uri);
   mongoc_cleanup ();
   return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
