/*
 * SPDX-FileCopyrightText: 2024 Hiredict Contributors
 *
 * SPDX-License-Identifier: BSD-3-Clause
 * SPDX-License-Identifier: LGPL-3.0-or-later
 *
 */

#ifndef __HIREDIS_H
#define __HIREDIS_H

#include <hiredict/hiredict.h>
#include <hiredis/read.h>
#include <hiredis/sds.h>
#include <hiredis/alloc.h>

#define HIREDIS_MAJOR HIREDICT_MAJOR
#define HIREDIS_MINOR HIREDICT_MINOR
#define HIREDIS_PATCH HIREDICT_PATCH
#define HIREDIS_SONAME HIREDICT_MAJOR

/* Connection type can be blocking or non-blocking and is set in the
 * least significant bit of the flags field in redictContext. */
#define REDIS_BLOCK REDICT_BLOCK

/* Connection may be disconnected before being free'd. The second bit
 * in the flags field is set when the context is connected. */
#define REDIS_CONNECTED REDICT_CONNECTED

/* The async API might try to disconnect cleanly and flush the output
 * buffer and read all subsequent replies before disconnecting.
 * This flag means no new commands can come in and the connection
 * should be terminated once all replies have been read. */
#define REDIS_DICONNECTING REDICT_DISCONNECTING

/* Flag specific to the async API which means that the context should be clean
 * up as soon as possible. */
#define REDIS_FREEING REDICT_FREEING

/* Flag that is set when an async callback is executed. */
#define REDIS_IN_CALLBACK REDICT_IN_CALLBACK

/* Flag that is set when the async context has one or more subscriptions. */
#define REDIS_SUBSCRIBED REDICT_SUBSCRIBED

/* Flag that is set when monitor mode is active */
#define REDIS_MONITORING REDICT_MONITORING

/* Flag that is set when we should set SO_REUSEADDR before calling bind() */
#define REDIS_REUSEADDR REDICT_REUSEADDR

/* Flag that is set when the async connection supports push replies. */
#define REDIS_SUPPORTS_PUSH REDICT_SUPPORTS_PUSH

/**
 * Flag that indicates the user does not want the context to
 * be automatically freed upon error
 */
#define REDIS_NO_AUTO_FREE REDICT_NO_AUTO_FREE

/* Flag that indicates the user does not want replies to be automatically freed */
#define REDIS_NO_AUTO_FREE_REPLIES REDICT_NO_AUTO_FREE_REPLIES

/* Flags to prefer IPv6 or IPv4 when doing DNS lookup. (If both are set,
 * AF_UNSPEC is used.) */
#define REDIS_PREFER_IPV4 REDICT_PREFER_IPV4
#define REDIS_PREFER_IPV6 REDICT_PREFER_IPV6

#define REDIS_KEEPALIVE_INTERVAL REDICT_KEEPALIVE_INTERVAL /* seconds */

/* number of times we retry to connect in the case of EADDRNOTAVAIL and
 * SO_REUSEADDR is being used. */
#define REDIS_CONNECT_RETRIES REDICT_CONNECT_RETRIES

/* RESP3 push helpers and callback prototypes */
#define redisIsPushReply(r) redictIsPushReply(r)
#define redisPushFn redictPushFn
#define redisAsyncPushFn redictAsyncPushFn

/* This is the reply object returned by redistCommand() */
#define redisReply redictReply

#define redisReaderCreate redictReaderCreate

/* Functions to format a command according to the protocol. */
#define redisvFormatCommand redictvFormatCommand
#define redisFormatCommand redictFormatCommand
#define redisFormatCommandArgv redictFormatCommandArgv
#define redisFormatSdsCommandArgv redictFormatSdsCommandArgv
#define redisFreeCommand redictFreeCommand
#define redisFreeSdsCommand redictFreeSdsCommand

#define redisConnectionType redictConnectionType

#define redisSsl redictSsl

#define REDIS_OPT_NONBLOCK REDICT_OPT_NONBLOCK
#define REDIS_OPT_REUSEADDR REDICT_OPT_REUSEADDR
#define REDIS_OPT_NOAUTOFREE REDICT_OPT_NOAUTOFREE /* Don't automatically free the async
													* object on a connection failure, or
													* other implicit conditions. Only free
													* on an explicit call to disconnect()
													* or free() */
#define REDIS_OPT_NO_PUSH_AUTOFREE REDICT_OPT_NO_PUSH_AUTOFREE /* Don't automatically intercept and
																* free RESP3 PUSH replies. */
#define REDIS_OPT_NOAUTOFREEREPLIES REDICT_OPT_NOAUTOFREEREPLIES /* Don't automatically free replies. */
#define REDIS_OPT_PREFER_IPV4 REDICT_OPT_PREFER_IPV4 /* Prefer IPv4 in DNS lookups. */
#define REDIS_OPT_PREFER_IPV6 REDICT_OPT_PREFER_IPV6 /* Prefer IPv6 in DNS lookups. */
#define REDIS_OPT_PREFER_IP_UNSPEC REDICT_OPT_PREFER_IP_UNSPEC

/* In Unix systems a file descriptor is a regular signed int, with -1
 * representing an invalid descriptor. In Windows it is a SOCKET
 * (32- or 64-bit unsigned integer depending on the architecture), where
 * all bits set (~0) is INVALID_SOCKET.  */
#define redisFD redictFD
#define REDIS_INVALID_FD REDICT_INVALID_FD

#define redisOptions redictOptions


/**
 * Helper macros to initialize options to their specified fields.
 */
#define REDIS_OPTIONS_SET_TCP(opts, ip_, port_) REDICT_OPTIONS_SET_TCP(opts, ip_, port_)
#define REDIS_OPTIONS_SET_UNIX(opts, path) REDICT_OPTIONS_SET_UNIX(opts, path)
#define REDIS_OPTIONS_SET_PRIVDATA(opts, data, dtor) REDICT_OPTIONS_SET_PRIVDATA(opts, data, dtor)

#define redisContextFuncs redictContextFuncs

/* Context for a connection to Redict */
#define redisContext redictContext


#define redisConnectWithOptions redictConnectWithOptions
#define redisConnect redictConnect
#define redisConnectWithTimeout redictConnectWithTimeout
#define redisConnectNonBlock redictConnectNonBlock
#define redisConnectBindNonBlock redictConnectBindNonBlock
#define redisConnectBindNonBlockWithReuse redictConnectBindNonBlockWithReuse
#define redisConnectUnix redictConnectUnix
#define redisConnectUnixWithTimeout redictConnectUnixWithTimeout
#define redisConnectUnixNonBlock redictConnectUnixNonBlock
#define redisConnectFd redictConnectFd

/**
 * Reconnect the given context using the saved information.
 *
 * This re-uses the exact same connect options as in the initial connection.
 * host, ip (or path), timeout and bind address are reused,
 * flags are used unmodified from the existing context.
 *
 * Returns REDICT_OK on successful connect or REDICT_ERR otherwise.
 */
#define redisReconnect redictReconnect

#define redisSetPushCallback redictSetPushCallback
#define redisSetTimeout redictSetTimeout
#define redisEnableKeepAlive redictEnableKeepAlive
#define redisEnableKeepAliveWithInterval redictEnableKeepAliveWithInterval
#define redisSetTcpUserTimeout redictSetTcpUserTimeout
#define redisFree redictFree
#define redisFreeKeepFd redictFreeKeepFd
#define redisBufferRead redictBufferRead
#define redisBufferWrite redictBufferWrite

/* In a blocking context, this function first checks if there are unconsumed
 * replies to return and returns one if so. Otherwise, it flushes the output
 * buffer to the socket and reads until it has a reply. In a non-blocking
 * context, it will return unconsumed replies until there are no more. */
#define redisGetReply redictGetReply
#define redisGetReplyFromReader redictGetReplyFromReader

/* Write a formatted command to the output buffer. Use these functions in blocking mode
 * to get a pipeline of commands. */
#define redisAppendFormattedCommand redictAppendFormattedCommand

/* Write a command to the output buffer. Use these functions in blocking mode
 * to get a pipeline of commands. */
#define redisvAppendCommand redictvAppendCommand
#define redisAppendCommand redictAppendCommand
#define redisAppendCommandArgv redictAppendCommandArgv

/* Issue a command to Redict. In a blocking context, it is identical to calling
 * redictAppendCommand, followed by redictGetReply. The function will return
 * NULL if there was an error in performing the request, otherwise it will
 * return the reply. In a non-blocking context, it is identical to calling
 * only redictAppendCommand and will always return NULL. */
#define redisvCommand redictvCommand
#define redisCommand redictCommand
#define redisCommandArgv redictCommandArgv

#endif
