/* ****************************************************************************
*
* mongoConnectionPoolInit - 
*/
int mongoConnectionPoolInit
(
  const char*  host,
  const char*  db,
  const char*  rplSet,
  const char*  username,
  const char*  passwd,
  bool         multitenant,
  double       timeout,
  int          writeConcern,
  int          poolSize,
  bool         semTimeStat
)
{
#ifdef UNIT_TEST
  /* Basically, we are mocking all the DB pool with a single connection. The getMongoConnection() and mongoReleaseConnection() methods
   * are mocked in similar way to ensure a coherent behaviour */
  setMongoConnectionForUnitTest(mongoConnect(host, db, rplSet, username, passwd, multitenant, writeConcern, timeout));
  return 0;
#else
  //
  // Create the pool
  //
  connectionPool  = (MongoConnection*) calloc(sizeof(MongoConnection), poolSize);
  if (connectionPool == NULL)
  {
    LM_E(("Runtime Error (insufficient memory to create connection pool of %d connections)", poolSize));
    return -1;
  }
  connectionPoolSize = poolSize;

  //
  // Initialize (connect) the pool
  //
  for (int ix = 0; ix < connectionPoolSize; ++ix)
  {
    connectionPool[ix].free       = true;
    connectionPool[ix].connection =
        mongoConnect(host, db, rplSet, username, passwd, multitenant, writeConcern, timeout);
  }

  //
  // Set up the semaphore protecting the pool itself (connectionPoolSem)
  //
  int r = sem_init(&connectionPoolSem, 0, 1);

  if (r != 0)
  {
    LM_E(("Runtime Error (cannot create connection pool semaphore)"));
    return -1;
  }

  //
  // Set up the semaphore protecting the set of connections of the pool (connectionSem)
  // Note that this is a counting semaphore, initialized to connectionPoolSize.
  //
  r = sem_init(&connectionSem, 0, connectionPoolSize);
  if (r != 0)
  {
    LM_E(("Runtime Error (cannot create connection semaphore-set)"));
    return -1;
  }

  // Measure accumulated semaphore waiting time?
  semStatistics = semTimeStat;

  return 0;
#endif
}
/* ****************************************************************************
*
* mongoConnectionPoolInit -
*/
int mongoConnectionPoolInit
(
    const char* host,
    const char* db,
    const char* rplSet,
    const char* username,
    const char* passwd,
    bool        multitenant,
    double      timeout,
    int         writeConcern,
    int         poolSize,
    bool        semTimeStat
)
{
    //
    // Create the pool
    //
    connectionPool     = (MongoConnection*) calloc(sizeof(MongoConnection), poolSize);
    if (connectionPool == NULL)
    {
        LM_E(("Runtime Error (insufficient memory to create connection pool of %d connections)", poolSize));
        return -1;
    }
    connectionPoolSize = poolSize;

    //
    // Initialize (connect) the pool
    //
    for (int ix = 0; ix < connectionPoolSize; ++ix)
    {
        connectionPool[ix].connection = mongoConnect(host, db, rplSet, username, passwd, multitenant, writeConcern, timeout);
        connectionPool[ix].free       = true;
    }

    //
    // Set up the semaphore protecting the pool itself (connectionPoolSem)
    //
    int r = sem_init(&connectionPoolSem, 0, 1);

    if (r != 0)
    {
        LM_E(("Runtime Error (cannot create connection pool semaphore)"));
        return -1;
    }

    //
    // Set up the semaphore protecting the set of connections of the pool (connectionSem)
    // Note that this is a counting semaphore, initialized to connectionPoolSize.
    //
    r = sem_init(&connectionSem, 0, connectionPoolSize);
    if (r != 0)
    {
        LM_E(("Runtime Error (cannot create connection semaphore-set)"));
        return -1;
    }

    // Measure accumulated semaphore waiting time?
    semStatistics = semTimeStat;

    return 0;
}