/*
 * Copyright 2009-present MongoDB, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <bson/bson.h>

#define QUERY(...) ELE_QUERY, __VA_ARGS__, NULL
#define SORT(...) ELE_SORT, __VA_ARGS__, NULL
#define LIMIT(var) ELE_LIMIT, (var)
#define COL_VIEW_CREATE(...) col_view_create ("", __VA_ARGS__, ELE_END)

typedef enum ele {
   ELE_SORT,
   ELE_LIMIT,
   ELE_QUERY,
   ELE_END,
} ele_t;

bson_t *
col_view_create (const char *stub, ...)
{
   bson_t *bson;
   va_list ap;
   ele_t type;
   int keep_going = 1;

   bcon_append_ctx_t ctx;
   bcon_append_ctx_init (&ctx);

   va_start (ap, stub);

   bson = bson_new ();

   while (keep_going) {
      type = va_arg (ap, ele_t);

      switch (type) {
      case ELE_SORT:
         BCON_APPEND_CTX (bson, &ctx, "sort", "{");
         bcon_append_ctx_va (bson, &ctx, &ap);
         BCON_APPEND_CTX (bson, &ctx, "}");
         break;
      case ELE_LIMIT: {
         int i = va_arg (ap, int);
         BCON_APPEND_CTX (bson, &ctx, "limit", BCON_INT32 (i));
         break;
      }
      case ELE_QUERY:
         BCON_APPEND_CTX (bson, &ctx, "query", "{");
         bcon_append_ctx_va (bson, &ctx, &ap);
         BCON_APPEND_CTX (bson, &ctx, "}");
         break;
      case ELE_END:
         keep_going = 0;
         break;
      default:
         BSON_ASSERT (0);
         break;
      }
   }

   va_end (ap);

   return bson;
}

int
main (void)
{
   bson_t *bson;
   char *json;

   bson = COL_VIEW_CREATE (SORT ("a", BCON_INT32 (1)), QUERY ("hello", "world"), LIMIT (10));

   json = bson_as_canonical_extended_json (bson, NULL);
   printf ("%s\n", json);
   bson_free (json);

   bson_destroy (bson);

   return 0;
}
