#include <assert.h>
#include <endian.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "bios.h"
#include "bios_table.h"

#define POINTER_CHECK(pointer)                                                 \
	do {                                                                   \
		if (pointer == NULL)                                           \
			return PLDM_ERROR_INVALID_DATA;                        \
	} while (0)

#define ATTR_TYPE_EXPECT(type, expected)                                       \
	do {                                                                   \
		if (type != expected && type != (expected | 0x80))             \
			return PLDM_ERROR_INVALID_DATA;                        \
	} while (0)

#define BUFFER_SIZE_EXPECT(current_size, expected_size)                        \
	do {                                                                   \
		if (current_size < expected_size)                              \
			return PLDM_ERROR_INVALID_LENGTH;                      \
	} while (0)

#define MEMBER_SIZE(type, member) sizeof(((struct type *)0)->member)

static uint16_t get_bios_string_handle()
{
	static uint16_t handle = 0;
	assert(handle != UINT16_MAX);

	return handle++;
}

size_t pldm_bios_table_string_entry_encode_length(uint16_t string_length)
{
	return sizeof(struct pldm_bios_string_table_entry) -
	       MEMBER_SIZE(pldm_bios_string_table_entry, name) + string_length;
}

void pldm_bios_table_string_entry_encode(void *entry, size_t entry_length,
					 const char *str, uint16_t str_length)
{
	size_t length = pldm_bios_table_string_entry_encode_length(str_length);
	assert(length <= entry_length);
	struct pldm_bios_string_table_entry *string_entry = entry;
	string_entry->string_handle = htole16(get_bios_string_handle());
	string_entry->string_length = htole16(str_length);
	memcpy(string_entry->name, str, str_length);
}

int pldm_bios_table_string_entry_encode_check(void *entry, size_t entry_length,
					      const char *str,
					      uint16_t str_length)
{
	if (str_length == 0)
		return PLDM_ERROR_INVALID_DATA;
	POINTER_CHECK(entry);
	POINTER_CHECK(str);
	size_t length = pldm_bios_table_string_entry_encode_length(str_length);
	BUFFER_SIZE_EXPECT(entry_length, length);
	pldm_bios_table_string_entry_encode(entry, entry_length, str,
					    str_length);
	return PLDM_SUCCESS;
}

uint16_t pldm_bios_table_string_entry_decode_handle(
    const struct pldm_bios_string_table_entry *entry)
{
	return le16toh(entry->string_handle);
}

uint16_t pldm_bios_table_string_entry_decode_string_length(
    const struct pldm_bios_string_table_entry *entry)
{
	return le16toh(entry->string_length);
}

uint16_t pldm_bios_table_string_entry_decode_string(
    const struct pldm_bios_string_table_entry *entry, char *buffer, size_t size)
{
	uint16_t length =
	    pldm_bios_table_string_entry_decode_string_length(entry);
	length = length < size ? length : size;
	memcpy(buffer, entry->name, length);
	buffer[length] = 0;
	return length;
}

int pldm_bios_table_string_entry_decode_string_check(
    const struct pldm_bios_string_table_entry *entry, char *buffer, size_t size)
{
	POINTER_CHECK(entry);
	POINTER_CHECK(buffer);
	size_t length =
	    pldm_bios_table_string_entry_decode_string_length(entry);
	BUFFER_SIZE_EXPECT(size, length + 1);
	pldm_bios_table_string_entry_decode_string(entry, buffer, size);
	return PLDM_SUCCESS;
}

static size_t string_table_entry_length(const void *table_entry)
{
	const struct pldm_bios_string_table_entry *entry = table_entry;
	return sizeof(*entry) - sizeof(entry->name) +
	       pldm_bios_table_string_entry_decode_string_length(entry);
}

static uint16_t get_bios_attr_handle()
{
	static uint16_t handle = 0;
	assert(handle != UINT16_MAX);

	return handle++;
}

static void attr_table_entry_encode_header(void *entry, size_t length,
					   uint8_t attr_type,
					   uint16_t string_handle)
{
	struct pldm_bios_attr_table_entry *attr_entry = entry;
	assert(sizeof(*attr_entry) <= length);
	attr_entry->attr_handle = htole16(get_bios_attr_handle());
	attr_entry->attr_type = attr_type;
	attr_entry->string_handle = htole16(string_handle);
}

size_t pldm_bios_table_attr_entry_enum_encode_length(uint8_t pv_num,
						     uint8_t def_num)
{
	return sizeof(struct pldm_bios_attr_table_entry) -
	       MEMBER_SIZE(pldm_bios_attr_table_entry, metadata) +
	       sizeof(pv_num) + pv_num * sizeof(uint16_t) + sizeof(def_num) +
	       def_num;
}

void pldm_bios_table_attr_entry_enum_encode(
    void *entry, size_t entry_length,
    const struct pldm_bios_table_attr_entry_enum_info *info)
{
	size_t length = pldm_bios_table_attr_entry_enum_encode_length(
	    info->pv_num, info->def_num);
	assert(length <= entry_length);
	uint8_t attr_type = info->read_only ? PLDM_BIOS_ENUMERATION_READ_ONLY
					    : PLDM_BIOS_ENUMERATION;
	attr_table_entry_encode_header(entry, entry_length, attr_type,
				       info->name_handle);
	struct pldm_bios_attr_table_entry *attr_entry = entry;
	attr_entry->metadata[0] = info->pv_num;
	uint16_t *pv_hdls =
	    (uint16_t *)(attr_entry->metadata + 1 /* sizeof(pv num) */);
	size_t i;
	for (i = 0; i < info->pv_num; i++)
		pv_hdls[i] = htole16(info->pv_handle[i]);
	attr_entry->metadata[1 + info->pv_num * sizeof(uint16_t)] =
	    info->def_num;
	memcpy(attr_entry->metadata + 1 /* sizeof(pv num) */ +
		   info->pv_num * sizeof(uint16_t) + 1 /* sizeof(def num)*/,
	       info->def_index, info->def_num);
}

int pldm_bios_table_attr_entry_enum_encode_check(
    void *entry, size_t entry_length,
    const struct pldm_bios_table_attr_entry_enum_info *info)
{
	POINTER_CHECK(entry);
	POINTER_CHECK(info);
	size_t length = pldm_bios_table_attr_entry_enum_encode_length(
	    info->pv_num, info->def_num);
	BUFFER_SIZE_EXPECT(entry_length, length);
	pldm_bios_table_attr_entry_enum_encode(entry, entry_length, info);
	return PLDM_SUCCESS;
}

#define ATTR_TYPE_EXPECT(type, expected)                                       \
	do {                                                                   \
		if (type != expected && type != (expected | 0x80))             \
			return PLDM_ERROR_INVALID_DATA;                        \
	} while (0)

uint8_t pldm_bios_table_attr_entry_enum_decode_pv_num(
    const struct pldm_bios_attr_table_entry *entry)
{
	return entry->metadata[0];
}

int pldm_bios_table_attr_entry_enum_decode_pv_num_check(
    const struct pldm_bios_attr_table_entry *entry, uint8_t *pv_num)
{
	POINTER_CHECK(entry);
	POINTER_CHECK(pv_num);
	ATTR_TYPE_EXPECT(entry->attr_type, PLDM_BIOS_ENUMERATION);
	*pv_num = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
	return PLDM_SUCCESS;
}

uint8_t pldm_bios_table_attr_entry_enum_decode_def_num(
    const struct pldm_bios_attr_table_entry *entry)
{
	uint8_t pv_num = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
	return entry->metadata[sizeof(uint8_t) /* pv_num */ +
			       sizeof(uint16_t) * pv_num];
}

int pldm_bios_table_attr_entry_enum_decode_def_num_check(
    const struct pldm_bios_attr_table_entry *entry, uint8_t *def_num)
{
	POINTER_CHECK(entry);
	POINTER_CHECK(def_num);
	ATTR_TYPE_EXPECT(entry->attr_type, PLDM_BIOS_ENUMERATION);
	*def_num = pldm_bios_table_attr_entry_enum_decode_def_num(entry);
	return PLDM_SUCCESS;
}

uint8_t pldm_bios_table_attr_entry_enum_decode_pv_hdls(
    const struct pldm_bios_attr_table_entry *entry, uint16_t *pv_hdls,
    uint8_t pv_num)
{
	uint8_t num = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
	num = num < pv_num ? num : pv_num;
	size_t i;
	for (i = 0; i < num; i++) {
		uint16_t *hdl = (uint16_t *)(entry->metadata + sizeof(uint8_t) +
					     i * sizeof(uint16_t));
		pv_hdls[i] = le16toh(*hdl);
	}
	return num;
}

int pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
    const struct pldm_bios_attr_table_entry *entry, uint16_t *pv_hdls,
    uint8_t pv_num)
{
	POINTER_CHECK(entry);
	POINTER_CHECK(pv_hdls);
	ATTR_TYPE_EXPECT(entry->attr_type, PLDM_BIOS_ENUMERATION);
	uint8_t num = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
	if (num != pv_num)
		return PLDM_ERROR_INVALID_DATA;
	pldm_bios_table_attr_entry_enum_decode_pv_hdls(entry, pv_hdls, pv_num);
	return PLDM_SUCCESS;
}

/** @brief Get length of an enum attribute entry
 */
static size_t
attr_table_entry_length_enum(const struct pldm_bios_attr_table_entry *entry)
{
	uint8_t pv_num = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
	uint8_t def_num = pldm_bios_table_attr_entry_enum_decode_def_num(entry);
	return pldm_bios_table_attr_entry_enum_encode_length(pv_num, def_num);
}

struct attr_table_string_entry_fields {
	uint8_t string_type;
	uint16_t min_length;
	uint16_t max_length;
	uint16_t def_length;
	uint8_t def_string[1];
} __attribute__((packed));

size_t pldm_bios_table_attr_entry_string_encode_length(uint16_t def_str_len)
{
	return sizeof(struct pldm_bios_attr_table_entry) -
	       MEMBER_SIZE(pldm_bios_attr_table_entry, metadata) +
	       sizeof(struct attr_table_string_entry_fields) -
	       MEMBER_SIZE(attr_table_string_entry_fields, def_string) +
	       def_str_len;
}

void pldm_bios_table_attr_entry_string_encode(
    void *entry, size_t entry_length,
    const struct pldm_bios_table_attr_entry_string_info *info)
{
	size_t length =
	    pldm_bios_table_attr_entry_string_encode_length(info->def_length);
	assert(length <= entry_length);
	uint8_t attr_type =
	    info->read_only ? PLDM_BIOS_STRING_READ_ONLY : PLDM_BIOS_STRING;
	attr_table_entry_encode_header(entry, entry_length, attr_type,
				       info->name_handle);
	struct pldm_bios_attr_table_entry *attr_entry = entry;
	struct attr_table_string_entry_fields *attr_fields =
	    (struct attr_table_string_entry_fields *)attr_entry->metadata;
	attr_fields->string_type = info->string_type;
	attr_fields->min_length = htole16(info->min_length);
	attr_fields->max_length = htole16(info->max_length);
	attr_fields->def_length = htole16(info->def_length);
	if (info->def_length != 0 && info->def_string != NULL)
		memcpy(attr_fields->def_string, info->def_string,
		       info->def_length);
}

int pldm_bios_table_attr_entry_string_encode_check(
    void *entry, size_t entry_length,
    const struct pldm_bios_table_attr_entry_string_info *info)
{
	POINTER_CHECK(entry);
	POINTER_CHECK(info);
	size_t length =
	    pldm_bios_table_attr_entry_string_encode_length(info->def_length);
	BUFFER_SIZE_EXPECT(entry_length, length);
	if (info->def_length > info->max_length ||
	    info->def_length < info->min_length ||
	    info->min_length > info->max_length)
		return PLDM_ERROR_INVALID_DATA;
	if (info->string_type > 5 && info->string_type != 0xFF)
		return PLDM_ERROR_INVALID_DATA;
	pldm_bios_table_attr_entry_string_encode(entry, entry_length, info);
	return PLDM_SUCCESS;
}

uint16_t pldm_bios_table_attr_entry_string_decode_def_string_length(
    const struct pldm_bios_attr_table_entry *entry)
{
	struct attr_table_string_entry_fields *fields =
	    (struct attr_table_string_entry_fields *)entry->metadata;
	return le16toh(fields->def_length);
}

int pldm_bios_table_attr_entry_string_decode_def_string_length_check(
    const struct pldm_bios_attr_table_entry *entry, uint16_t *def_string_length)
{
	POINTER_CHECK(entry);
	POINTER_CHECK(def_string_length);
	ATTR_TYPE_EXPECT(entry->attr_type, PLDM_BIOS_STRING);
	*def_string_length =
	    pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
	return PLDM_SUCCESS;
}

/** @brief Get length of a string attribute entry
 */
static size_t
attr_table_entry_length_string(const struct pldm_bios_attr_table_entry *entry)
{
	uint16_t def_str_len =
	    pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
	return pldm_bios_table_attr_entry_string_encode_length(def_str_len);
}

struct attr_table_entry {
	uint8_t attr_type;
	size_t (*entry_length_handler)(
	    const struct pldm_bios_attr_table_entry *);
};

static struct attr_table_entry attr_table_entrys[] = {
    {.attr_type = PLDM_BIOS_ENUMERATION,
     .entry_length_handler = attr_table_entry_length_enum},
    {.attr_type = PLDM_BIOS_ENUMERATION_READ_ONLY,
     .entry_length_handler = attr_table_entry_length_enum},
    {.attr_type = PLDM_BIOS_STRING,
     .entry_length_handler = attr_table_entry_length_string},
    {.attr_type = PLDM_BIOS_STRING_READ_ONLY,
     .entry_length_handler = attr_table_entry_length_string},
};

#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))

static struct attr_table_entry *find_attr_table_entry_by_type(uint8_t attr_type)
{
	size_t i;
	for (i = 0; i < ARRAY_SIZE(attr_table_entrys); i++) {
		if (attr_type == attr_table_entrys[i].attr_type)
			return &attr_table_entrys[i];
	}
	return NULL;
}

static size_t attr_table_entry_length(const void *table_entry)
{
	const struct pldm_bios_attr_table_entry *entry = table_entry;
	struct attr_table_entry *attr_table_entry =
	    find_attr_table_entry_by_type(entry->attr_type);
	assert(attr_table_entry != NULL);
	assert(attr_table_entry->entry_length_handler != NULL);

	return attr_table_entry->entry_length_handler(entry);
}

size_t pldm_bios_table_attr_value_entry_encode_enum_length(uint8_t count)
{
	return sizeof(struct pldm_bios_attr_val_table_entry) - 1 +
	       sizeof(count) + count;
}

void pldm_bios_table_attr_value_entry_encode_enum(
    void *entry, size_t entry_length, uint16_t attr_handle, uint8_t attr_type,
    uint8_t count, uint8_t *handles)
{
	size_t length =
	    pldm_bios_table_attr_value_entry_encode_enum_length(count);
	assert(length <= entry_length);

	struct pldm_bios_attr_val_table_entry *table_entry = entry;
	table_entry->attr_handle = htole16(attr_handle);
	table_entry->attr_type = attr_type;
	table_entry->value[0] = count;
	if (count != 0)
		memcpy(&table_entry->value[1], handles, count);
}

int pldm_bios_table_attr_value_entry_encode_enum_check(
    void *entry, size_t entry_length, uint16_t attr_handle, uint8_t attr_type,
    uint8_t count, uint8_t *handles)
{
	POINTER_CHECK(entry);
	if (count != 0 && handles == NULL)
		return PLDM_ERROR_INVALID_DATA;
	ATTR_TYPE_EXPECT(attr_type, PLDM_BIOS_ENUMERATION);
	size_t length =
	    pldm_bios_table_attr_value_entry_encode_enum_length(count);
	BUFFER_SIZE_EXPECT(entry_length, length);
	pldm_bios_table_attr_value_entry_encode_enum(
	    entry, entry_length, attr_handle, attr_type, count, handles);
	return PLDM_SUCCESS;
}

size_t
pldm_bios_table_attr_value_entry_encode_string_length(uint16_t string_length)
{
	return sizeof(struct pldm_bios_attr_val_table_entry) - 1 +
	       sizeof(string_length) + string_length;
}

void pldm_bios_table_attr_value_entry_encode_string(
    void *entry, size_t entry_length, uint16_t attr_handle, uint8_t attr_type,
    uint16_t str_length, const char *str)
{
	size_t length =
	    pldm_bios_table_attr_value_entry_encode_string_length(str_length);
	assert(length <= entry_length);

	struct pldm_bios_attr_val_table_entry *table_entry = entry;
	table_entry->attr_handle = htole16(attr_handle);
	table_entry->attr_type = attr_type;
	if (str_length != 0)
		memcpy(table_entry->value + sizeof(str_length), str,
		       str_length);
	str_length = htole16(str_length);
	memcpy(table_entry->value, &str_length, sizeof(str_length));
}

int pldm_bios_table_attr_value_entry_encode_string_check(
    void *entry, size_t entry_length, uint16_t attr_handle, uint8_t attr_type,
    uint16_t str_length, const char *str)
{
	POINTER_CHECK(entry);
	if (str_length != 0 && str == NULL)
		return PLDM_ERROR_INVALID_DATA;
	ATTR_TYPE_EXPECT(attr_type, PLDM_BIOS_STRING);
	size_t length =
	    pldm_bios_table_attr_value_entry_encode_string_length(str_length);
	BUFFER_SIZE_EXPECT(entry_length, length);
	pldm_bios_table_attr_value_entry_encode_string(
	    entry, entry_length, attr_handle, attr_type, str_length, str);
	return PLDM_SUCCESS;
}

struct pldm_bios_table_iter {
	const uint8_t *table_data;
	size_t table_len;
	size_t current_pos;
	size_t (*entry_length_handler)(const void *table_entry);
};

struct pldm_bios_table_iter *
pldm_bios_table_iter_create(const void *table, size_t length,
			    enum pldm_bios_table_types type)
{
	struct pldm_bios_table_iter *iter = malloc(sizeof(*iter));
	assert(iter != NULL);
	iter->table_data = table;
	iter->table_len = length;
	iter->current_pos = 0;
	iter->entry_length_handler = NULL;
	switch (type) {
	case PLDM_BIOS_STRING_TABLE:
		iter->entry_length_handler = string_table_entry_length;
		break;
	case PLDM_BIOS_ATTR_TABLE:
		iter->entry_length_handler = attr_table_entry_length;
		break;
	case PLDM_BIOS_ATTR_VAL_TABLE:
		break;
	}

	return iter;
}

void pldm_bios_table_iter_free(struct pldm_bios_table_iter *iter)
{
	free(iter);
}

#define pad_and_check_max 7
bool pldm_bios_table_iter_is_end(const struct pldm_bios_table_iter *iter)
{
	if (iter->table_len - iter->current_pos <= pad_and_check_max)
		return true;
	return false;
}

void pldm_bios_table_iter_next(struct pldm_bios_table_iter *iter)
{
	if (pldm_bios_table_iter_is_end(iter))
		return;
	const void *entry = iter->table_data + iter->current_pos;
	iter->current_pos += iter->entry_length_handler(entry);
}

const void *pldm_bios_table_iter_value(struct pldm_bios_table_iter *iter)
{
	return iter->table_data + iter->current_pos;
}

static const void *
pldm_bios_table_entry_find(struct pldm_bios_table_iter *iter, const void *key,
			   int (*equal)(const void *entry, const void *key))
{
	const void *entry;
	while (!pldm_bios_table_iter_is_end(iter)) {
		entry = pldm_bios_table_iter_value(iter);
		if (equal(entry, key))
			return entry;
		pldm_bios_table_iter_next(iter);
	}
	return NULL;
}

static int string_table_handle_equal(const void *entry, const void *key)
{
	const struct pldm_bios_string_table_entry *string_entry = entry;
	uint16_t handle = *(uint16_t *)key;
	if (pldm_bios_table_string_entry_decode_handle(string_entry) == handle)
		return true;
	return false;
}

struct string_equal_arg {
	uint16_t str_length;
	const char *str;
};

static int string_table_string_equal(const void *entry, const void *key)
{
	const struct pldm_bios_string_table_entry *string_entry = entry;
	const struct string_equal_arg *arg = key;
	if (arg->str_length !=
	    pldm_bios_table_string_entry_decode_string_length(string_entry))
		return false;
	if (memcmp(string_entry->name, arg->str, arg->str_length) != 0)
		return false;
	return true;
}

const struct pldm_bios_string_table_entry *
pldm_bios_table_string_find_by_string(const void *table, size_t length,
				      const char *str)
{
	uint16_t str_length = strlen(str);
	struct string_equal_arg arg = {str_length, str};
	struct pldm_bios_table_iter *iter =
	    pldm_bios_table_iter_create(table, length, PLDM_BIOS_STRING_TABLE);
	const void *entry =
	    pldm_bios_table_entry_find(iter, &arg, string_table_string_equal);
	pldm_bios_table_iter_free(iter);
	return entry;
}

const struct pldm_bios_string_table_entry *
pldm_bios_table_string_find_by_handle(const void *table, size_t length,
				      uint16_t handle)
{
	struct pldm_bios_table_iter *iter =
	    pldm_bios_table_iter_create(table, length, PLDM_BIOS_STRING_TABLE);
	const void *entry = pldm_bios_table_entry_find(
	    iter, &handle, string_table_handle_equal);
	pldm_bios_table_iter_free(iter);
	return entry;
}
