#pragma once

/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
 * 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 as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include <stdint.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/bits.h>
#include <osmocom/core/defs.h>

/*! \defgroup msgb Message buffers
 *  @{
 */

/*! \file msgb.h */

#define MSGB_DEBUG

/*! \brief Osmocom message buffer */
struct msgb {
	struct llist_head list; /*!< \brief linked list header */


	/* Part of which TRX logical channel we were received / transmitted */
	/* FIXME: move them into the control buffer */
	union {
		void *dst; /*!< \brief reference of origin/destination */
		struct gsm_bts_trx *trx;
	};
	struct gsm_lchan *lchan; /*!< \brief logical channel */

	unsigned char *l1h; /*!< \brief pointer to Layer1 header (if any) */
	unsigned char *l2h; /*!< \brief pointer to A-bis layer 2 header: OML, RSL(RLL), NS */
	unsigned char *l3h; /*!< \brief pointer to Layer 3 header. For OML: FOM; RSL: 04.08; GPRS: BSSGP */
	unsigned char *l4h; /*!< \brief pointer to layer 4 header */

	unsigned long cb[5]; /*!< \brief control buffer */

	uint16_t data_len;   /*!< \brief length of underlying data array */
	uint16_t len;	     /*!< \brief length of bytes used in msgb */

	unsigned char *head;	/*!< \brief start of underlying memory buffer */
	unsigned char *tail;	/*!< \brief end of message in buffer */
	unsigned char *data;	/*!< \brief start of message in buffer */
	unsigned char _data[0]; /*!< \brief optional immediate data array */
};

extern struct msgb *msgb_alloc(uint16_t size, const char *name);
extern void msgb_free(struct msgb *m);
extern void msgb_enqueue(struct llist_head *queue, struct msgb *msg);
extern struct msgb *msgb_dequeue(struct llist_head *queue);
extern void msgb_reset(struct msgb *m);
uint16_t msgb_length(const struct msgb *msg);
extern const char *msgb_hexdump(const struct msgb *msg);
extern int msgb_resize_area(struct msgb *msg, uint8_t *area,
	int old_size, int new_size);
extern struct msgb *msgb_copy(const struct msgb *msg, const char *name);
static int msgb_test_invariant(const struct msgb *msg) __attribute__((pure));

#ifdef MSGB_DEBUG
#include <osmocom/core/panic.h>
#define MSGB_ABORT(msg, fmt, args ...) do {		\
	osmo_panic("msgb(%p): " fmt, msg, ## args);	\
	} while(0)
#else
#define MSGB_ABORT(msg, fmt, args ...)
#endif

/*! \brief obtain L1 header of msgb */
#define msgb_l1(m)	((void *)(m->l1h))
/*! \brief obtain L2 header of msgb */
#define msgb_l2(m)	((void *)(m->l2h))
/*! \brief obtain L3 header of msgb */
#define msgb_l3(m)	((void *)(m->l3h))
/*! \brief obtain SMS header of msgb */
#define msgb_sms(m)	((void *)(m->l4h))

/*! \brief determine length of L1 message
 *  \param[in] msgb message buffer
 *  \returns size of L1 message in bytes
 *
 * This function computes the number of bytes between the tail of the
 * message and the layer 1 header.
 */
static inline unsigned int msgb_l1len(const struct msgb *msgb)
{
	return msgb->tail - (uint8_t *)msgb_l1(msgb);
}

/*! \brief determine length of L2 message
 *  \param[in] msgb message buffer
 *  \returns size of L2 message in bytes
 *
 * This function computes the number of bytes between the tail of the
 * message and the layer 2 header.
 */
static inline unsigned int msgb_l2len(const struct msgb *msgb)
{
	return msgb->tail - (uint8_t *)msgb_l2(msgb);
}

/*! \brief determine length of L3 message
 *  \param[in] msgb message buffer
 *  \returns size of L3 message in bytes
 *
 * This function computes the number of bytes between the tail of the
 * message and the layer 3 header.
 */
static inline unsigned int msgb_l3len(const struct msgb *msgb)
{
	return msgb->tail - (uint8_t *)msgb_l3(msgb);
}

/*! \brief determine the length of the header
 *  \param[in] msgb message buffer
 *  \returns number of bytes between start of buffer and start of msg
 *
 * This function computes the length difference between the underlying
 * data buffer and the used section of the \a msgb.
 */
static inline unsigned int msgb_headlen(const struct msgb *msgb)
{
	return msgb->len - msgb->data_len;
}

/*! \brief determine how much tail room is left in msgb
 *  \param[in] msgb message buffer
 *  \returns number of bytes remaining at end of msgb
 *
 * This function computes the amount of octets left in the underlying
 * data buffer after the end of the message.
 */
static inline int msgb_tailroom(const struct msgb *msgb)
{
	return (msgb->head + msgb->data_len) - msgb->tail;
}

/*! \brief determine the amount of headroom in msgb
 *  \param[in] msgb message buffer
 *  \returns number of bytes left ahead of message start in msgb
 *
 * This function computes the amount of bytes left in the underlying
 * data buffer before the start of the actual message.
 */
static inline int msgb_headroom(const struct msgb *msgb)
{
	return (msgb->data - msgb->head);
}

/*! \brief append data to end of message buffer
 *  \param[in] msgb message buffer
 *  \param[in] len number of bytes to append to message
 *  \returns pointer to start of newly-appended data
 *
 * This function will move the \a tail pointer of the message buffer \a
 * len bytes further, thus enlarging the message by \a len bytes.
 *
 * The return value is a pointer to start of the newly added section at
 * the end of the message and can be used for actually filling/copying
 * data into it.
 */
static inline unsigned char *msgb_put(struct msgb *msgb, unsigned int len)
{
	unsigned char *tmp = msgb->tail;
	if (msgb_tailroom(msgb) < (int) len)
		MSGB_ABORT(msgb, "Not enough tailroom msgb_put (%u < %u)\n",
			   msgb_tailroom(msgb), len);
	msgb->tail += len;
	msgb->len += len;
	return tmp;
}

/*! \brief append a uint8 value to the end of the message
 *  \param[in] msgb message buffer
 *  \param[in] word unsigned 8bit byte to be appended
 */
static inline void msgb_put_u8(struct msgb *msgb, uint8_t word)
{
	uint8_t *space = msgb_put(msgb, 1);
	space[0] = word & 0xFF;
}

/*! \brief append a uint16 value to the end of the message
 *  \param[in] msgb message buffer
 *  \param[in] word unsigned 16bit byte to be appended
 */
static inline void msgb_put_u16(struct msgb *msgb, uint16_t word)
{
	uint8_t *space = msgb_put(msgb, 2);
	osmo_store16be(word, space);
}

/*! \brief append a uint32 value to the end of the message
 *  \param[in] msgb message buffer
 *  \param[in] word unsigned 32bit byte to be appended
 */
static inline void msgb_put_u32(struct msgb *msgb, uint32_t word)
{
	uint8_t *space = msgb_put(msgb, 4);
	osmo_store32be(word, space);
}

/*! \brief remove data from end of message
 *  \param[in] msgb message buffer
 *  \param[in] len number of bytes to remove from end
 */
static inline unsigned char *msgb_get(struct msgb *msgb, unsigned int len)
{
	unsigned char *tmp = msgb->tail - len;
	if (msgb_length(msgb) < len)
		MSGB_ABORT(msgb, "msgb too small to get %u (len %u)\n",
			   len, msgb_length(msgb));
	msgb->tail -= len;
	msgb->len -= len;
	return tmp;
}

/*! \brief remove uint8 from end of message
 *  \param[in] msgb message buffer
 *  \returns 8bit value taken from end of msgb
 */
static inline uint8_t msgb_get_u8(struct msgb *msgb)
{
	uint8_t *space = msgb_get(msgb, 1);
	return space[0];
}

/*! \brief remove uint16 from end of message
 *  \param[in] msgb message buffer
 *  \returns 16bit value taken from end of msgb
 */
static inline uint16_t msgb_get_u16(struct msgb *msgb)
{
	uint8_t *space = msgb_get(msgb, 2);
	return osmo_load16be(space);
}

/*! \brief remove uint32 from end of message
 *  \param[in] msgb message buffer
 *  \returns 32bit value taken from end of msgb
 */
static inline uint32_t msgb_get_u32(struct msgb *msgb)
{
	uint8_t *space = msgb_get(msgb, 4);
	return osmo_load32be(space);
}

/*! \brief prepend (push) some data to start of message
 *  \param[in] msgb message buffer
 *  \param[in] len number of bytes to pre-pend
 *  \returns pointer to newly added portion at start of \a msgb
 *
 * This function moves the \a data pointer of the \ref msgb further
 * to the front (by \a len bytes), thereby enlarging the message by \a
 * len bytes.
 *
 * The return value is a pointer to the newly added section in the
 * beginning of the message.  It can be used to fill/copy data into it.
 */
static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len)
{
	if (msgb_headroom(msgb) < (int) len)
		MSGB_ABORT(msgb, "Not enough headroom msgb_push (%u < %u)\n",
			   msgb_headroom(msgb), len);
	msgb->data -= len;
	msgb->len += len;
	return msgb->data;
}

/*! \brief prepend a uint8 value to the head of the message
 *  \param[in] msgb message buffer
 *  \param[in] word unsigned 8bit byte to be prepended
 */
static inline void msgb_push_u8(struct msgb *msg, uint8_t word)
{
	uint8_t *space = msgb_push(msg, 1);
	space[0] = word;
}

/*! \brief prepend a uint16 value to the head of the message
 *  \param[in] msgb message buffer
 *  \param[in] word unsigned 16bit byte to be prepended
 */
static inline void msgb_push_u16(struct msgb *msg, uint16_t word)
{
	uint16_t *space = (uint16_t *) msgb_push(msg, 2);
	osmo_store16be(word, space);
}

/*! \brief prepend a uint32 value to the head of the message
 *  \param[in] msgb message buffer
 *  \param[in] word unsigned 32bit byte to be prepended
 */
static inline void msgb_push_u32(struct msgb *msg, uint32_t word)
{
	uint32_t *space = (uint32_t *) msgb_push(msg, 4);
	osmo_store32be(word, space);
}

/*! \brief remove (pull) a header from the front of the message buffer
 *  \param[in] msgb message buffer
 *  \param[in] len number of octets to be pulled
 *  \returns pointer to new start of msgb
 *
 * This function moves the \a data pointer of the \ref msgb further back
 * in the message, thereby shrinking the size of the message by \a len
 * bytes.
 */
static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len)
{
	msgb->len -= len;
	return msgb->data += len;
}

/*! \brief remove (pull) all headers in front of l3h from the message buffer.
 *  \param[in] msgb message buffer with a valid l3h
 *  \returns pointer to new start of msgb (l3h)
 *
 * This function moves the \a data pointer of the \ref msgb further back
 * in the message, thereby shrinking the size of the message.
 * l1h and l2h will be cleared.
 */
static inline unsigned char *msgb_pull_to_l3(struct msgb *msg)
{
	unsigned char *ret = msgb_pull(msg, msg->l3h - msg->data);
	msg->l1h = msg->l2h = NULL;
	return ret;
}

/*! \brief remove (pull) all headers in front of l2h from the message buffer.
 *  \param[in] msgb message buffer with a valid l2h
 *  \returns pointer to new start of msgb (l2h)
 *
 * This function moves the \a data pointer of the \ref msgb further back
 * in the message, thereby shrinking the size of the message.
 * l1h will be cleared.
 */
static inline unsigned char *msgb_pull_to_l2(struct msgb *msg)
{
	unsigned char *ret = msgb_pull(msg, msg->l2h - msg->data);
	msg->l1h = NULL;
	return ret;
}

/*! \brief remove uint8 from front of message
 *  \param[in] msgb message buffer
 *  \returns 8bit value taken from end of msgb
 */
static inline uint8_t msgb_pull_u8(struct msgb *msgb)
{
	uint8_t *space = msgb_pull(msgb, 1) - 1;
	return space[0];
}

/*! \brief remove uint16 from front of message
 *  \param[in] msgb message buffer
 *  \returns 16bit value taken from end of msgb
 */
static inline uint16_t msgb_pull_u16(struct msgb *msgb)
{
	uint8_t *space = msgb_pull(msgb, 2) - 2;
	return osmo_load16be(space);
}

/*! \brief remove uint32 from front of message
 *  \param[in] msgb message buffer
 *  \returns 32bit value taken from end of msgb
 */
static inline uint32_t msgb_pull_u32(struct msgb *msgb)
{
	uint8_t *space = msgb_pull(msgb, 4) - 4;
	return osmo_load32be(space);
}

/*! \brief Increase headroom of empty msgb, reducing the tailroom
 *  \param[in] msg message buffer
 *  \param[in] len amount of extra octets to be reserved as headroom
 *
 * This function reserves some memory at the beginning of the underlying
 * data buffer.  The idea is to reserve space in case further headers
 * have to be pushed to the \ref msgb during further processing.
 *
 * Calling this function leads to undefined reusults if it is called on
 * a non-empty \ref msgb.
 */
static inline void msgb_reserve(struct msgb *msg, int len)
{
	msg->data += len;
	msg->tail += len;
}

/*! \brief Trim the msgb to a given absolute length
 *  \param[in] msg message buffer
 *  \param[in] len new total length of buffer
 *  \returns 0 in case of success, negative in case of error
 */
static inline int msgb_trim(struct msgb *msg, int len)
{
	if (len < 0)
		MSGB_ABORT(msg, "Negative length is not allowed\n");
	if (len > msg->data_len)
		return -1;

	msg->len = len;
	msg->tail = msg->data + len;

	return 0;
}

/*! \brief Trim the msgb to a given layer3 length
 *  \param[in] msg message buffer
 *  \param[in] l3len new layer3 length
 *  \returns 0 in case of success, negative in case of error
 */
static inline int msgb_l3trim(struct msgb *msg, int l3len)
{
	return msgb_trim(msg, (msg->l3h - msg->data) + l3len);
}

/*! \brief Allocate message buffer with specified headroom
 *  \param[in] size size in bytes, including headroom
 *  \param[in] headroom headroom in bytes
 *  \param[in] name human-readable name
 *  \returns allocated message buffer with specified headroom
 *
 * This function is a convenience wrapper around \ref msgb_alloc
 * followed by \ref msgb_reserve in order to create a new \ref msgb with
 * user-specified amount of headroom.
 */
static inline struct msgb *msgb_alloc_headroom(int size, int headroom,
						const char *name)
{
	osmo_static_assert(size > headroom, headroom_bigger);

	struct msgb *msg = msgb_alloc(size, name);
	if (msg)
		msgb_reserve(msg, headroom);
	return msg;
}

/*! \brief Check a message buffer for consistency
 *  \param[in] msg message buffer
 *  \returns 0 (false) if inconsistent, != 0 (true) otherwise
 */
static inline int msgb_test_invariant(const struct msgb *msg)
{
	const unsigned char *lbound;
	if (!msg || !msg->data || !msg->tail ||
	    (msg->data + msg->len != msg->tail) ||
	    (msg->data < msg->head) ||
	    (msg->tail > msg->head + msg->data_len))
		return 0;

	lbound = msg->head;

	if (msg->l1h) {
		if (msg->l1h < lbound)
			return 0;
		lbound = msg->l1h;
	}
	if (msg->l2h) {
		if (msg->l2h < lbound)
			return 0;
		lbound = msg->l2h;
	}
	if (msg->l3h) {
		if (msg->l3h < lbound)
			return 0;
		lbound = msg->l3h;
	}
	if (msg->l4h) {
		if (msg->l4h < lbound)
			return 0;
		lbound = msg->l4h;
	}

	return lbound <= msg->head +  msg->data_len;
}

/* non inline functions to ease binding */

uint8_t *msgb_data(const struct msgb *msg);

void *msgb_talloc_ctx_init(void *root_ctx, unsigned int pool_size);
void msgb_set_talloc_ctx(void *ctx) OSMO_DEPRECATED("Use msgb_talloc_ctx_init() instead");

/*! @} */
