/*
 * Copyright (C) Tildeslash Ltd. All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 *
 * You must obey the GNU General Public License in all respects
 * for all of the code used other than OpenSSL.
 */


#ifndef ZDB_INCLUDED
#define ZDB_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif

#include <stdbool.h>

/**
 * Include this interface in your C code to import the libzdb API.
 *
 * @file
 */

/* --------------------------------------------------------------- Version */

#define LIBZDB_MAJOR    @VERSION_MAJOR@
#define LIBZDB_MINOR    @VERSION_MINOR@
#define LIBZDB_REVISION @VERSION_REVISION@

#define LIBZDB_VERSION  "@VERSION@"
#define LIBZDB_VERSION_NUMBER ((LIBZDB_MAJOR * 1000000) + (LIBZDB_MINOR * 1000) + LIBZDB_REVISION)

/* ------------------------------------------------- libzdb API interfaces */

#include <SQLException.h>
#include <URL.h>
#include <ResultSet.h>
#include <PreparedStatement.h>
#include <Connection.h>
#include <ConnectionPool.h>

#ifdef __cplusplus
}
#endif


#ifndef __cplusplus
/* --------------------------------------------------------- Utility Macro */


/**
 * @brief Provides a default value if the expression is NULL, 0, or negative.
 *
 * The valueOr macro is a convenient way to handle potentially unset or error
 * values returned by libzdb functions. It works with pointers, integers, and
 * floating-point types.
 *
 * This macro evaluates the expression only once, making it safe to use with
 * function calls or expressions that may have side effects.
 *
 * For pointers:
 *   - Returns the default value if the expression evaluates to NULL.
 *   - Otherwise, returns the original pointer value.
 *
 * For integers and floating-point types:
 *   - Returns the default value if the expression evaluates to 0 or any negative value.
 *   - Otherwise, returns the original numeric value.
 *
 * @param expr The expression to evaluate (typically a libzdb function call)
 * @param default_value The value to return if expr is NULL, 0, or negative
 *
 * @return If expr is not NULL, 0, or negative, returns expr.
 *         Otherwise, returns default_value.
 *
 * @note This macro uses a GNU C extension and is compatible with GCC and Clang.
 *       It may not work with other C compilers.
 *
 * @example
 * // Usage with string (pointer) return type
 * const char* host = valueOr(URL_getHost(url), "localhost");
 * printf("Host: %s\n", host);
 * 
 * // Usage with integer return type
 * int port = valueOr(ResultSet_getInt(r, 1), 5432);
 * printf("Port: %d\n", port);
 *
 * // Usage with floating-point return type
 * double percent = valueOr(ResultSet_getDouble(r, 1), 1.0);
 * printf("Percent: %.1f\n", percent);
 */
#define valueOr(expr, default_value) \
    ({ \
        __typeof__(expr) _t = (expr); \
        (_t < 0 || _t == 0) ? (default_value) : _t; \
    })
    
#endif /* not __cplusplus */
#endif
