#include <mongoc/mongoc-deprioritized-servers-private.h>
#include <mongoc/mongoc-set-private.h>

// Dedicated non-zero value to avoid confusing "key is present with a NULL item"
// from "key is not present" (also NULL).
#define MONGOC_DEPRIORITIZED_SERVERS_ITEM_VALUE ((void *)1)

struct _mongoc_deprioritized_servers_t {
   // Use server ID (uint32_t) as keys to identify deprioritized servers.
   mongoc_set_t *ids;
};

mongoc_deprioritized_servers_t *
mongoc_deprioritized_servers_new(void)
{
   mongoc_deprioritized_servers_t *const ret = bson_malloc(sizeof(*ret));

   *ret = (mongoc_deprioritized_servers_t){
      .ids = mongoc_set_new(1u, NULL, NULL),
   };

   return ret;
}

void
mongoc_deprioritized_servers_destroy(mongoc_deprioritized_servers_t *ds)
{
   if (!ds) {
      return;
   }

   mongoc_set_destroy(ds->ids);
   bson_free(ds);
}

void
mongoc_deprioritized_servers_add(mongoc_deprioritized_servers_t *ds, const mongoc_server_description_t *sd)
{
   BSON_ASSERT_PARAM(ds);
   BSON_ASSERT_PARAM(sd);

   mongoc_set_add(ds->ids, mongoc_server_description_id(sd), MONGOC_DEPRIORITIZED_SERVERS_ITEM_VALUE);
}

bool
mongoc_deprioritized_servers_contains(const mongoc_deprioritized_servers_t *ds, const mongoc_server_description_t *sd)
{
   BSON_ASSERT_PARAM(ds);
   BSON_ASSERT_PARAM(sd);

   return mongoc_set_get_const(ds->ids, mongoc_server_description_id(sd)) == MONGOC_DEPRIORITIZED_SERVERS_ITEM_VALUE;
}
