/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
#ifndef PLDM_MSGBUF_H
#define PLDM_MSGBUF_H

#ifdef __cplusplus
/*
 * Fix up C11's _Static_assert() vs C++'s static_assert().
 *
 * Can we please have nice things for once.
 */
// NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
#define _Static_assert(...) static_assert(__VA_ARGS__)
extern "C" {
#endif

#include <libpldm/base.h>
#include <libpldm/pldm_types.h>

#include <assert.h>
#include <endian.h>
#include <limits.h>
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>

struct pldm_msgbuf {
	uint8_t *cursor;
	ssize_t remaining;
};

/**
 * @brief Initialize pldm buf struct for buf extractor
 *
 * @param[out] ctx - pldm_msgbuf context for extractor
 * @param[in] minsize - The minimum required length of buffer `buf`
 * @param[in] buf - buffer to be extracted
 * @param[in] len - size of buffer
 *
 * @return PLDM_SUCCESS if all buffer accesses were in-bounds,
 * PLDM_ERROR_INVALID_DATA if pointer parameters are invalid, or
 * PLDM_ERROR_INVALID_LENGTH if length constraints are violated.
 */
__attribute__((no_sanitize("pointer-overflow"))) static inline int
pldm_msgbuf_init(struct pldm_msgbuf *ctx, size_t minsize, const void *buf,
		 size_t len)
{
	uint8_t *end;

	if (!ctx || !buf) {
		return PLDM_ERROR_INVALID_DATA;
	}

	if ((minsize > len) || (len > SSIZE_MAX)) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	end = (uint8_t *)buf + len;
	if (end && end < (uint8_t *)buf) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	ctx->cursor = (uint8_t *)buf;
	ctx->remaining = (ssize_t)len;

	return PLDM_SUCCESS;
}

/**
 * @brief Validate buffer overflow state
 *
 * @param[in] ctx - pldm_msgbuf context for extractor
 *
 * @return PLDM_SUCCESS if there are zero or more bytes of data that remain
 * unread from the buffer. Otherwise, PLDM_ERROR_INVALID_LENGTH indicates that a
 * prior accesses would have occurred beyond the bounds of the buffer, and
 * PLDM_ERROR_INVALID_DATA indicates that the provided context was not a valid
 * pointer.
 */
static inline int pldm_msgbuf_validate(struct pldm_msgbuf *ctx)
{
	if (!ctx) {
		return PLDM_ERROR_INVALID_DATA;
	}

	return ctx->remaining >= 0 ? PLDM_SUCCESS : PLDM_ERROR_INVALID_LENGTH;
}

/**
 * @brief Test whether a message buffer has been exactly consumed
 *
 * @param[in] ctx - pldm_msgbuf context for extractor
 *
 * @return PLDM_SUCCESS iff there are zero bytes of data that remain unread from
 * the buffer and no overflow has occurred. Otherwise, PLDM_ERROR_INVALID_LENGTH
 * indicates that an incorrect sequence of accesses have occurred, and
 * PLDM_ERROR_INVALID_DATA indicates that the provided context was not a valid
 * pointer.
 */
static inline int pldm_msgbuf_consumed(struct pldm_msgbuf *ctx)
{
	if (!ctx) {
		return PLDM_ERROR_INVALID_DATA;
	}

	return ctx->remaining == 0 ? PLDM_SUCCESS : PLDM_ERROR_INVALID_LENGTH;
}

/**
 * @brief Destroy the pldm buf
 *
 * @param[in] ctx - pldm_msgbuf context for extractor
 *
 * @return PLDM_SUCCESS if all buffer accesses were in-bounds,
 * PLDM_ERROR_INVALID_DATA if the ctx parameter is invalid, or
 * PLDM_ERROR_INVALID_LENGTH if prior accesses would have occurred beyond the
 * bounds of the buffer.
 */
static inline int pldm_msgbuf_destroy(struct pldm_msgbuf *ctx)
{
	int valid;

	if (!ctx) {
		return PLDM_ERROR_INVALID_DATA;
	}

	valid = pldm_msgbuf_validate(ctx);

	ctx->cursor = NULL;
	ctx->remaining = 0;

	return valid;
}

/**
 * @brief Destroy the pldm_msgbuf instance, and check that the underlying buffer
 * has been completely consumed without overflow
 *
 * @param[in] ctx - pldm_msgbuf context
 *
 * @return PLDM_SUCCESS if all buffer access were in-bounds and completely
 * consume the underlying buffer. Otherwise, PLDM_ERROR_INVALID_DATA if the ctx
 * parameter is invalid, or PLDM_ERROR_INVALID_LENGTH if prior accesses would
 * have occurred byond the bounds of the buffer
 */
static inline int pldm_msgbuf_destroy_consumed(struct pldm_msgbuf *ctx)
{
	int consumed;

	if (!ctx) {
		return PLDM_ERROR_INVALID_DATA;
	}

	consumed = pldm_msgbuf_consumed(ctx);

	ctx->cursor = NULL;
	ctx->remaining = 0;

	return consumed;
}

/**
 * @brief pldm_msgbuf extractor for a uint8_t
 *
 * @param[inout] ctx - pldm_msgbuf context for extractor
 * @param[out] dst - destination of extracted value
 *
 * @return PLDM_SUCCESS if buffer accesses were in-bounds,
 * PLDM_ERROR_INVALID_LENGTH otherwise.
 * PLDM_ERROR_INVALID_DATA if input a invalid ctx
 */
static inline int pldm_msgbuf_extract_uint8(struct pldm_msgbuf *ctx,
					    uint8_t *dst)
{
	if (!ctx || !ctx->cursor || !dst) {
		return PLDM_ERROR_INVALID_DATA;
	}

	ctx->remaining -= sizeof(*dst);
	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	*dst = *((uint8_t *)(ctx->cursor));
	ctx->cursor++;
	return PLDM_SUCCESS;
}

static inline int pldm_msgbuf_extract_int8(struct pldm_msgbuf *ctx, int8_t *dst)
{
	if (!ctx || !ctx->cursor || !dst) {
		return PLDM_ERROR_INVALID_DATA;
	}

	ctx->remaining -= sizeof(*dst);
	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	*dst = *((int8_t *)(ctx->cursor));
	ctx->cursor++;
	return PLDM_SUCCESS;
}

static inline int pldm_msgbuf_extract_uint16(struct pldm_msgbuf *ctx,
					     uint16_t *dst)
{
	uint16_t ldst;

	if (!ctx || !ctx->cursor || !dst) {
		return PLDM_ERROR_INVALID_DATA;
	}

	// Check for buffer overflow. If we overflow, account for the request as
	// negative values in ctx->remaining. This way we can debug how far
	// we've overflowed.
	ctx->remaining -= sizeof(ldst);

	// Prevent the access if it would overflow. First, assert so we blow up
	// the test suite right at the point of failure. However, cater to
	// -DNDEBUG by explicitly testing that the access is valid.
	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	// Use memcpy() to have the compiler deal with any alignment
	// issues on the target architecture
	memcpy(&ldst, ctx->cursor, sizeof(ldst));

	// Only assign the target value once it's correctly decoded
	*dst = le16toh(ldst);
	ctx->cursor += sizeof(ldst);

	return PLDM_SUCCESS;
}

static inline int pldm_msgbuf_extract_int16(struct pldm_msgbuf *ctx,
					    int16_t *dst)
{
	int16_t ldst;

	if (!ctx || !ctx->cursor || !dst) {
		return PLDM_ERROR_INVALID_DATA;
	}

	ctx->remaining -= sizeof(ldst);
	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	memcpy(&ldst, ctx->cursor, sizeof(ldst));

	*dst = le16toh(ldst);
	ctx->cursor += sizeof(ldst);

	return PLDM_SUCCESS;
}

static inline int pldm_msgbuf_extract_uint32(struct pldm_msgbuf *ctx,
					     uint32_t *dst)
{
	uint32_t ldst;

	if (!ctx || !ctx->cursor || !dst) {
		return PLDM_ERROR_INVALID_DATA;
	}

	ctx->remaining -= sizeof(ldst);
	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	memcpy(&ldst, ctx->cursor, sizeof(ldst));

	*dst = le32toh(ldst);
	ctx->cursor += sizeof(ldst);

	return PLDM_SUCCESS;
}

static inline int pldm_msgbuf_extract_int32(struct pldm_msgbuf *ctx,
					    int32_t *dst)
{
	int32_t ldst;

	if (!ctx || !ctx->cursor || !dst) {
		return PLDM_ERROR_INVALID_DATA;
	}

	ctx->remaining -= sizeof(ldst);
	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	memcpy(&ldst, ctx->cursor, sizeof(ldst));

	*dst = le32toh(ldst);
	ctx->cursor += sizeof(ldst);

	return PLDM_SUCCESS;
}

static inline int pldm_msgbuf_extract_real32(struct pldm_msgbuf *ctx,
					     real32_t *dst)
{
	uint32_t ldst;

	if (!ctx || !ctx->cursor || !dst) {
		return PLDM_ERROR_INVALID_DATA;
	}

	ctx->remaining -= sizeof(ldst);
	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	_Static_assert(sizeof(*dst) == sizeof(ldst),
		       "Mismatched type sizes for dst and ldst");
	memcpy(&ldst, ctx->cursor, sizeof(ldst));
	ldst = le32toh(ldst);
	memcpy(dst, &ldst, sizeof(*dst));
	ctx->cursor += sizeof(*dst);

	return PLDM_SUCCESS;
}

#define pldm_msgbuf_extract(ctx, dst)                                          \
	_Generic((*(dst)),                                                     \
		uint8_t: pldm_msgbuf_extract_uint8,                            \
		int8_t: pldm_msgbuf_extract_int8,                              \
		uint16_t: pldm_msgbuf_extract_uint16,                          \
		int16_t: pldm_msgbuf_extract_int16,                            \
		uint32_t: pldm_msgbuf_extract_uint32,                          \
		int32_t: pldm_msgbuf_extract_int32,                            \
		real32_t: pldm_msgbuf_extract_real32)(ctx, dst)

static inline int pldm_msgbuf_extract_array_uint8(struct pldm_msgbuf *ctx,
						  uint8_t *dst, size_t count)
{
	if (!ctx || !ctx->cursor || !dst) {
		return PLDM_ERROR_INVALID_DATA;
	}

	if (!count) {
		return PLDM_SUCCESS;
	}

	if (count >= SSIZE_MAX) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	ctx->remaining -= (ssize_t)count;
	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	memcpy(dst, ctx->cursor, count);
	ctx->cursor += count;

	return PLDM_SUCCESS;
}

#define pldm_msgbuf_extract_array(ctx, dst, count)                             \
	_Generic((*(dst)), uint8_t: pldm_msgbuf_extract_array_uint8)(ctx, dst, \
								     count)

static inline int pldm_msgbuf_insert_uint32(struct pldm_msgbuf *ctx,
					    const uint32_t src)
{
	uint32_t val = htole32(src);

	if (!ctx || !ctx->cursor) {
		return PLDM_ERROR_INVALID_DATA;
	}

	ctx->remaining -= sizeof(src);
	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	memcpy(ctx->cursor, &val, sizeof(val));
	ctx->cursor += sizeof(src);

	return PLDM_SUCCESS;
}

static inline int pldm_msgbuf_insert_uint16(struct pldm_msgbuf *ctx,
					    const uint16_t src)
{
	uint16_t val = htole16(src);

	if (!ctx || !ctx->cursor) {
		return PLDM_ERROR_INVALID_DATA;
	}

	ctx->remaining -= sizeof(src);
	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	memcpy(ctx->cursor, &val, sizeof(val));
	ctx->cursor += sizeof(src);

	return PLDM_SUCCESS;
}

static inline int pldm_msgbuf_insert_uint8(struct pldm_msgbuf *ctx,
					   const uint8_t src)
{
	if (!ctx || !ctx->cursor) {
		return PLDM_ERROR_INVALID_DATA;
	}

	ctx->remaining -= sizeof(src);
	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	memcpy(ctx->cursor, &src, sizeof(src));
	ctx->cursor += sizeof(src);

	return PLDM_SUCCESS;
}

static inline int pldm_msgbuf_insert_int32(struct pldm_msgbuf *ctx,
					   const int32_t src)
{
	int32_t val = htole32(src);

	if (!ctx || !ctx->cursor) {
		return PLDM_ERROR_INVALID_DATA;
	}

	ctx->remaining -= sizeof(src);
	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	memcpy(ctx->cursor, &val, sizeof(val));
	ctx->cursor += sizeof(src);

	return PLDM_SUCCESS;
}

static inline int pldm_msgbuf_insert_int16(struct pldm_msgbuf *ctx,
					   const int16_t src)
{
	int16_t val = htole16(src);

	if (!ctx || !ctx->cursor) {
		return PLDM_ERROR_INVALID_DATA;
	}

	ctx->remaining -= sizeof(src);
	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	memcpy(ctx->cursor, &val, sizeof(val));
	ctx->cursor += sizeof(src);

	return PLDM_SUCCESS;
}

static inline int pldm_msgbuf_insert_int8(struct pldm_msgbuf *ctx,
					  const int8_t src)
{
	if (!ctx || !ctx->cursor) {
		return PLDM_ERROR_INVALID_DATA;
	}

	ctx->remaining -= sizeof(src);
	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	memcpy(ctx->cursor, &src, sizeof(src));
	ctx->cursor += sizeof(src);

	return PLDM_SUCCESS;
}

#define pldm_msgbuf_insert(dst, src)                                           \
	_Generic((src),                                                        \
		uint8_t: pldm_msgbuf_insert_uint8,                             \
		int8_t: pldm_msgbuf_insert_int8,                               \
		uint16_t: pldm_msgbuf_insert_uint16,                           \
		int16_t: pldm_msgbuf_insert_int16,                             \
		uint32_t: pldm_msgbuf_insert_uint32,                           \
		int32_t: pldm_msgbuf_insert_int32)(dst, src)

static inline int pldm_msgbuf_insert_array_uint8(struct pldm_msgbuf *ctx,
						 const uint8_t *src,
						 size_t count)
{
	if (!ctx || !ctx->cursor || !src) {
		return PLDM_ERROR_INVALID_DATA;
	}

	if (!count) {
		return PLDM_SUCCESS;
	}

	if (count >= SSIZE_MAX) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	ctx->remaining -= (ssize_t)count;
	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	memcpy(ctx->cursor, src, count);
	ctx->cursor += count;

	return PLDM_SUCCESS;
}

#define pldm_msgbuf_insert_array(dst, src, count)                              \
	_Generic((*(src)), uint8_t: pldm_msgbuf_insert_array_uint8)(dst, src,  \
								    count)

static inline int pldm_msgbuf_span_required(struct pldm_msgbuf *ctx,
					    size_t required, void **cursor)
{
	if (!ctx || !ctx->cursor || !cursor || *cursor) {
		return PLDM_ERROR_INVALID_DATA;
	}

	if (required > SSIZE_MAX) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	ctx->remaining -= (ssize_t)required;
	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	*cursor = ctx->cursor;
	ctx->cursor += required;

	return PLDM_SUCCESS;
}

static inline int pldm_msgbuf_span_remaining(struct pldm_msgbuf *ctx,
					     void **cursor, size_t *len)
{
	if (!ctx || !ctx->cursor || !cursor || *cursor || !len) {
		return PLDM_ERROR_INVALID_DATA;
	}

	assert(ctx->remaining >= 0);
	if (ctx->remaining < 0) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	*cursor = ctx->cursor;
	ctx->cursor += ctx->remaining;
	*len = ctx->remaining;
	ctx->remaining = 0;

	return PLDM_SUCCESS;
}
#ifdef __cplusplus
}
#endif

#endif /* BUF_H */
