#ifndef QDB_API_DEQUE_H
#define QDB_API_DEQUE_H

//! \file deque.h
//! \defgroup deque Distributed double-ended queues operations
//! \warning All functions declared in this file are experimental.

/*
 *
 * Official quasardb C API 2.5.0
 * 522fcd7 2018-04-20 15:49:49 +0000
 *
 * Copyright (c) 2009-2018, quasardb SAS
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * Neither the name of quasardb nor the names of its contributors may
 *      be used to endorse or promote products derived from this software
 *      without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY QUASARDB AND CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* clang-format off */

#include "client.h"

#ifdef __cplusplus
extern "C" {
#endif

//! \ingroup deque
//! \brief Returns the number of elements in a deque.
//!
//! A double ended queue is transparently distributed accross the nodes and
//! supports efficient insertion at the beginning and the end of the deque.
//! Random access to the elements of the deque is also supported.
//! Deques have no limit to the number of elements they may hold.
//!
//! It is an error to call this function on a non existing deque.
//!
//! The complexity of this function is constant.
//!
//! \param handle A valid handle previously initialized by \ref qdb_open or
//! \ref qdb_open_tcp.
//!
//! \param alias A pointer to a null-terminated UTF-8 string representing the
//! alias of the deque.
//!
//! \param[out] size A pointer to an integer that will receive the size of the deque.
//!
//! \return A \ref qdb_error_t code indicating success or failure.
//!
//! \warning This function is experimental.
QDB_API_LINKAGE qdb_error_t
qdb_deque_size(
    qdb_handle_t handle,
    const char * alias,
    qdb_size_t * size
);

//! \ingroup deque
//! \brief Returns the element at the designated index.
//!
//! A double ended queue is transparently distributed across the nodes and
//! supports efficient insertion at the beginning and the end of the deque.
//! Random access to the elements of the deque is also supported.
//! Deques have no limit to the number of elements they may hold.
//!
//! The index is zero-based starting at the first element (front) of the deque.
//!
//! It is an error to call this function on a non existing deque.
//!
//! The complexity of this function is constant.
//!
//! \param handle A valid handle previously initialized by \ref qdb_open or
//! \ref qdb_open_tcp.
//!
//! \param alias A pointer to a null-terminated UTF-8 string representing the
//! alias of the deque.
//!
//! \param index The zero-based index to the element of the deque
//!
//! \param[out] content A pointer to a pointer to a buffer that will be API-allocated
//! to receive the result of the operation, if successful
//!
//! \param[out] content_length A pointer to the size of the API-allocated buffer
//!
//! \return A \ref qdb_error_t code indicating success or failure.
//!
//! \warning This function is experimental.
QDB_API_LINKAGE qdb_error_t
qdb_deque_get_at(
    qdb_handle_t handle,
    const char * alias,
    qdb_int_t index,
    const void ** content,
    qdb_size_t * content_length
);

//! \ingroup deque
//! \brief Updates element at the designated index.
//!
//! A double ended queue is transparently distributed across the nodes and
//! supports efficient insertion at the beginning and the end of the deque.
//! Random access to the elements of the deque is also supported.
//! Deques have no limit to the number of elements they may hold.
//!
//! There is no arbitrary limit to the size of an element within a deque.
//!
//! The index is zero-based starting at the first element (front) of the deque.
//!
//! It is an error to call this function on a non existing deque.
//!
//! The complexity of this function is constant.
//!
//! \param handle A valid handle previously initialized by \ref qdb_open or
//! \ref qdb_open_tcp.
//!
//! \param alias A pointer to a null-terminated UTF-8 string representing the
//! alias of the deque.
//!
//! \param index The zero-based index to the element of the deque
//!
//! \param content A to a pointer to a buffer with the new content
//!
//! \param content_length The size of the buffer
//!
//! \return A \ref qdb_error_t code indicating success or failure.
//!
//! \warning This function is experimental.
QDB_API_LINKAGE qdb_error_t
qdb_deque_set_at(
    qdb_handle_t handle,
    const char * alias,
    qdb_int_t index,
    const void * content,
    qdb_size_t content_length
);

//! \ingroup deque
//! \brief Atomically appends an element to the front of the deque
//!
//! A double ended queue is transparently distributed across the nodes and
//! supports efficient insertion at the beginning and the end of the deque.
//! Random access to the elements of the deque is also supported.
//! Deques have no limit to the number of elements they may hold.
//!
//! There is no arbitrary limit to the size of an element within a deque.
//!
//! Calling this function on a non-existing deque will create the deque.
//!
//! The complexity of this function is constant.
//!
//! \param handle A valid handle previously initialized by \ref qdb_open or
//! \ref qdb_open_tcp.
//!
//! \param alias A pointer to a null-terminated UTF-8 string representing the
//! alias of the deque.
//!
//! \param content A to a pointer to a buffer with the new entry content
//!
//! \param content_length The size of the buffer
//!
//! \return A \ref qdb_error_t code indicating success or failure.
//!
//! \warning This function is experimental.
QDB_API_LINKAGE qdb_error_t
qdb_deque_push_front(
    qdb_handle_t handle,
    const char * alias,
    const void * content,
    qdb_size_t content_length
);

//! \ingroup deque
//! \brief Atomically appends an element to the end of the deque
//!
//! A double ended queue is transparently distributed across the nodes and
//! supports efficient insertion at the beginning and the end of the deque.
//! Random access to the elements of the deque is also supported.
//! Deques have no limit to the number of elements they may hold.
//!
//! There is no arbitrary limit to the size of an element within a deque.
//!
//! Calling this function on a non-existing deque will create the deque.
//!
//! The complexity of this function is constant.
//!
//! \param handle A valid handle previously initialized by \ref qdb_open or
//! \ref qdb_open_tcp.
//!
//! \param alias A pointer to a null-terminated UTF-8 string representing the
//! alias of the deque.
//!
//! \param content A to a pointer to a buffer with the new entry content
//!
//! \param content_length The size of the buffer
//!
//! \return A \ref qdb_error_t code indicating success or failure.
//!
//! \warning This function is experimental.
QDB_API_LINKAGE qdb_error_t
qdb_deque_push_back(
    qdb_handle_t handle,
    const char * alias,
    const void * content,
    qdb_size_t content_length
);

//! \ingroup deque
//! \brief Atomically removes the element at the front of the deque and return
//! its content
//!
//! A double ended queue is transparently distributed across the nodes and
//! supports efficient insertion at the beginning and the end of the deque.
//! Random access to the elements of the deque is also supported.
//! Deques have no limit to the number of elements they may hold.
//!
//! Removing the last element of the deque will not remove the entry but leave
//! an empty deque.
//!
//! It is an error to call this function on a non existing or empty deque.
//!
//! The complexity of this function is constant.
//!
//! \param handle A valid handle previously initialized by \ref qdb_open or
//! \ref qdb_open_tcp.
//!
//! \param alias A pointer to a null-terminated UTF-8 string representing the
//! alias of the deque.
//!
//! \param[out] content A pointer to a pointer to a buffer that will be API-allocated
//! to receive the content of the first element, if successful
//!
//! \param[out] content_length A pointer to the size of the API-allocated buffer
//!
//! \return A \ref qdb_error_t code indicating success or failure.
//!
//! \warning This function is experimental.
QDB_API_LINKAGE qdb_error_t
qdb_deque_pop_front(
    qdb_handle_t handle,
    const char * alias,
    const void ** content,
    qdb_size_t * content_length
);

//! \ingroup deque
//! \brief Atomically remove the element at the end of the deque and return
//! its content
//!
//! A double ended queue is transparently distributed across the nodes and
//! supports efficient insertion at the beginning and the end of the deque.
//! Random access to the elements of the deque is also supported.
//! Deques have no limit to the number of elements they may hold.
//!
//! Removing the last element of the deque will not remove the entry but leave
//! an empty deque.
//!
//! It is an error to call this function on a non existing or emtpy deque.
//!
//! The complexity of this function is constant.
//!
//! \param handle A valid handle previously initialized by \ref qdb_open or
//! \ref qdb_open_tcp.
//!
//! \param[out] alias A pointer to a null-terminated UTF-8 string representing the
//! alias of the deque.
//!
//! \param[out] content A pointer to a pointer to a buffer that will be API-allocated
//! to receive the content of the last element, if successful
//!
//! \param content_length A pointer to the size of the API-allocated buffer
//!
//! \return A \ref qdb_error_t code indicating success or failure.
//!
//! \warning This function is experimental.
QDB_API_LINKAGE qdb_error_t
qdb_deque_pop_back(
    qdb_handle_t handle,
    const char * alias,
    const void ** content,
    qdb_size_t * content_length
);

//! \ingroup deque
//! \brief Returns the content of the first element in the deque
//!
//! A double ended queue is transparently distributed across the nodes and
//! supports efficient insertion at the beginning and the end of the deque.
//! Random access to the elements of the deque is also supported.
//! Deques have no limit to the number of elements they may hold.
//!
//! It is an error to call this function on a non existing or empty deque.
//!
//! The complexity of this function is constant.
//!
//! \param handle A valid handle previously initialized by \ref qdb_open or
//! \ref qdb_open_tcp.
//!
//! \param alias A pointer to a null-terminated UTF-8 string representing the
//! alias of the deque.
//!
//! \param[out] content A pointer to a pointer to a buffer that will be API-allocated
//! to receive the content of the first element, if successful
//!
//! \param[out] content_length A pointer to the size of the API-allocated buffer
//!
//! \return A \ref qdb_error_t code indicating success or failure.
//!
//! \warning This function is experimental.
QDB_API_LINKAGE qdb_error_t
qdb_deque_front(
    qdb_handle_t handle,
    const char * alias,
    const void ** content,
    qdb_size_t * content_length
);

//! \ingroup deque
//! \brief Returns the content of the last element in the deque
//!
//! A double ended queue is transparently distributed across the nodes and
//! supports efficient insertion at the beginning and the end of the deque.
//! Random access to the elements of the deque is also supported.
//! Deques have no limit to the number of elements they may hold.
//!
//! It is an error to call this function on a non existing or empty deque.
//!
//! The complexity of this function is constant.
//!
//! \param handle A valid handle previously initialized by \ref qdb_open or
//! \ref qdb_open_tcp.
//!
//! \param alias A pointer to a null-terminated UTF-8 string representing the
//! alias of the deque.
//!
//! \param[out] content A pointer to a pointer to a buffer that will be API-allocated
//! to receive the content of the last element, if successful
//!
//! \param[out] content_length A pointer to the size of the API-allocated buffer
//!
//! \return A \ref qdb_error_t code indicating success or failure.
//!
//! \warning This function is experimental.
QDB_API_LINKAGE qdb_error_t
qdb_deque_back(
    qdb_handle_t handle,
    const char * alias,
    const void ** content,
    qdb_size_t * content_length
);

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* QDB_API_DEQUE_H */
