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

#include "fru.h"

int encode_get_fru_record_table_metadata_req(uint8_t instance_id,
					     struct pldm_msg *msg,
					     size_t payload_length)
{
	if (msg == NULL) {
		return PLDM_ERROR_INVALID_DATA;
	}

	if (payload_length != PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	struct pldm_header_info header = {0};
	header.instance = instance_id;
	header.msg_type = PLDM_REQUEST;
	header.pldm_type = PLDM_FRU;
	header.command = PLDM_GET_FRU_RECORD_TABLE_METADATA;
	int rc = pack_pldm_header(&header, &(msg->hdr));
	if (PLDM_SUCCESS != rc) {
		return rc;
	}

	return PLDM_SUCCESS;
}

int decode_get_fru_record_table_metadata_resp(
    const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
    uint8_t *fru_data_major_version, uint8_t *fru_data_minor_version,
    uint32_t *fru_table_maximum_size, uint32_t *fru_table_length,
    uint16_t *total_record_set_identifiers, uint16_t *total_table_records,
    uint32_t *checksum)
{
	if (msg == NULL || completion_code == NULL ||
	    fru_data_major_version == NULL || fru_data_minor_version == NULL ||
	    fru_table_maximum_size == NULL || fru_table_length == NULL ||
	    total_record_set_identifiers == NULL ||
	    total_table_records == NULL || checksum == NULL) {
		return PLDM_ERROR_INVALID_DATA;
	}

	*completion_code = msg->payload[0];
	if (PLDM_SUCCESS != *completion_code) {
		return PLDM_SUCCESS;
	}

	if (payload_length != PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	struct pldm_get_fru_record_table_metadata_resp *response =
	    (struct pldm_get_fru_record_table_metadata_resp *)msg->payload;

	*fru_data_major_version = response->fru_data_major_version;
	*fru_data_minor_version = response->fru_data_minor_version;
	*fru_table_maximum_size = le32toh(response->fru_table_maximum_size);
	*fru_table_length = le32toh(response->fru_table_length);
	*total_record_set_identifiers =
	    le16toh(response->total_record_set_identifiers);
	*total_table_records = le16toh(response->total_table_records);
	*checksum = le32toh(response->checksum);

	return PLDM_SUCCESS;
}

int encode_get_fru_record_table_metadata_resp(
    uint8_t instance_id, uint8_t completion_code,
    uint8_t fru_data_major_version, uint8_t fru_data_minor_version,
    uint32_t fru_table_maximum_size, uint32_t fru_table_length,
    uint16_t total_record_set_identifiers, uint16_t total_table_records,
    uint32_t checksum, struct pldm_msg *msg)
{

	if (msg == NULL) {
		return PLDM_ERROR_INVALID_DATA;
	}

	struct pldm_header_info header = {0};
	header.msg_type = PLDM_RESPONSE;
	header.instance = instance_id;
	header.pldm_type = PLDM_FRU;
	header.command = PLDM_GET_FRU_RECORD_TABLE_METADATA;
	int rc = pack_pldm_header(&header, &(msg->hdr));
	if (PLDM_SUCCESS != rc) {
		return rc;
	}

	struct pldm_get_fru_record_table_metadata_resp *response =
	    (struct pldm_get_fru_record_table_metadata_resp *)msg->payload;
	response->completion_code = completion_code;
	if (response->completion_code == PLDM_SUCCESS) {
		response->fru_data_major_version = fru_data_major_version;
		response->fru_data_minor_version = fru_data_minor_version;
		response->fru_table_maximum_size =
		    htole32(fru_table_maximum_size);
		response->fru_table_length = htole32(fru_table_length);
		response->total_record_set_identifiers =
		    htole16(total_record_set_identifiers);
		response->total_table_records = htole16(total_table_records);
		response->checksum = htole32(checksum);
	}

	return PLDM_SUCCESS;
}

int decode_get_fru_record_table_req(const struct pldm_msg *msg,
				    size_t payload_length,
				    uint32_t *data_transfer_handle,
				    uint8_t *transfer_operation_flag)
{
	if (msg == NULL || data_transfer_handle == NULL ||
	    transfer_operation_flag == NULL) {
		return PLDM_ERROR_INVALID_DATA;
	}

	if (payload_length != PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	struct pldm_get_fru_record_table_req *req =
	    (struct pldm_get_fru_record_table_req *)msg->payload;

	*data_transfer_handle = le32toh(req->data_transfer_handle);
	*transfer_operation_flag = req->transfer_operation_flag;

	return PLDM_SUCCESS;
}

int encode_get_fru_record_table_resp(uint8_t instance_id,
				     uint8_t completion_code,
				     uint32_t next_data_transfer_handle,
				     uint8_t transfer_flag,
				     struct pldm_msg *msg)
{
	struct pldm_header_info header = {0};
	int rc = PLDM_ERROR_INVALID_DATA;

	header.msg_type = PLDM_RESPONSE;
	header.instance = instance_id;
	header.pldm_type = PLDM_FRU;
	header.command = PLDM_GET_FRU_RECORD_TABLE;

	if (msg == NULL) {
		return rc;
	}

	if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
		return rc;
	}

	struct pldm_get_fru_record_table_resp *resp =
	    (struct pldm_get_fru_record_table_resp *)msg->payload;

	resp->completion_code = completion_code;

	if (resp->completion_code == PLDM_SUCCESS) {

		resp->next_data_transfer_handle =
		    htole32(next_data_transfer_handle);
		resp->transfer_flag = transfer_flag;
	}

	return PLDM_SUCCESS;
}

int encode_fru_record(uint8_t *fru_table, size_t total_size, size_t *curr_size,
		      uint16_t record_set_id, uint8_t record_type,
		      uint8_t num_frus, uint8_t encoding, uint8_t *tlvs,
		      size_t tlvs_size)
{
	size_t record_hdr_size = sizeof(struct pldm_fru_record_data_format) -
				 sizeof(struct pldm_fru_record_tlv);

	if (fru_table == NULL || curr_size == NULL || !tlvs_size) {
		return PLDM_ERROR_INVALID_DATA;
	}
	if ((*curr_size + record_hdr_size + tlvs_size) != total_size) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	struct pldm_fru_record_data_format *record =
	    (struct pldm_fru_record_data_format *)(fru_table + *curr_size);
	record->record_set_id = htole16(record_set_id);
	record->record_type = record_type;
	record->num_fru_fields = num_frus;
	record->encoding_type = encoding;
	*curr_size += record_hdr_size;

	if (tlvs) {
		memcpy(fru_table + *curr_size, tlvs, tlvs_size);
		*curr_size += tlvs_size;
	}

	return PLDM_SUCCESS;
}

static bool is_table_end(const struct pldm_fru_record_data_format *p,
			 const void *table, size_t table_size)
{
	return p ==
	       (const struct pldm_fru_record_data_format *)((uint8_t *)table +
							    table_size);
}

void get_fru_record_by_option(const uint8_t *table, size_t table_size,
			      uint8_t *record_table, size_t *record_size,
			      uint16_t rsi, uint8_t rt, uint8_t ft)
{
	const struct pldm_fru_record_data_format *record_data_src =
	    (const struct pldm_fru_record_data_format *)table;
	struct pldm_fru_record_data_format *record_data_dest;
	int count = 0;

	const struct pldm_fru_record_tlv *tlv;
	size_t len;
	uint8_t *pos = record_table;

	while (!is_table_end(record_data_src, table, table_size)) {
		if ((record_data_src->record_set_id != htole16(rsi) &&
		     rsi != 0) ||
		    (record_data_src->record_type != rt && rt != 0)) {
			tlv = record_data_src->tlvs;
			for (int i = 0; i < record_data_src->num_fru_fields;
			     i++) {
				len = sizeof(*tlv) - 1 + tlv->length;
				tlv = (const struct pldm_fru_record_tlv
					   *)((char *)tlv + len);
			}
			record_data_src =
			    (const struct pldm_fru_record_data_format *)(tlv);
			continue;
		}

		len = sizeof(struct pldm_fru_record_data_format) -
		      sizeof(struct pldm_fru_record_tlv);

		assert(pos - record_table + len < *record_size);
		memcpy(pos, record_data_src, len);

		record_data_dest = (struct pldm_fru_record_data_format *)pos;
		pos += len;

		tlv = record_data_src->tlvs;
		count = 0;
		for (int i = 0; i < record_data_src->num_fru_fields; i++) {
			len = sizeof(*tlv) - 1 + tlv->length;
			if (tlv->type == ft || ft == 0) {
				assert(pos - record_table + len < *record_size);
				memcpy(pos, tlv, len);
				pos += len;
				count++;
			}
			tlv = (const struct pldm_fru_record_tlv *)((char *)tlv +
								   len);
		}
		record_data_dest->num_fru_fields = count;
		record_data_src =
		    (const struct pldm_fru_record_data_format *)(tlv);
	}

	*record_size = pos - record_table;
}

int encode_get_fru_record_by_option_req(
    uint8_t instance_id, uint32_t data_transfer_handle,
    uint16_t fru_table_handle, uint16_t record_set_identifier,
    uint8_t record_type, uint8_t field_type, uint8_t transfer_op_flag,
    struct pldm_msg *msg, size_t payload_length)
{

	if (msg == NULL) {
		return PLDM_ERROR_INVALID_DATA;
	}

	if (payload_length !=
	    sizeof(struct pldm_get_fru_record_by_option_req)) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	struct pldm_header_info header = {0};
	header.instance = instance_id;
	header.msg_type = PLDM_REQUEST;
	header.pldm_type = PLDM_FRU;
	header.command = PLDM_GET_FRU_RECORD_BY_OPTION;
	int rc = pack_pldm_header(&header, &(msg->hdr));
	if (rc != PLDM_SUCCESS) {
		return rc;
	}

	struct pldm_get_fru_record_by_option_req *req =
	    (struct pldm_get_fru_record_by_option_req *)msg->payload;

	req->data_transfer_handle = htole32(data_transfer_handle);
	req->fru_table_handle = htole16(fru_table_handle);
	req->record_set_identifier = htole16(record_set_identifier);
	req->record_type = record_type;
	req->field_type = field_type;
	req->transfer_op_flag = transfer_op_flag;

	return PLDM_SUCCESS;
}

int decode_get_fru_record_by_option_req(
    const struct pldm_msg *msg, size_t payload_length,
    uint32_t *data_transfer_handle, uint16_t *fru_table_handle,
    uint16_t *record_set_identifier, uint8_t *record_type, uint8_t *field_type,
    uint8_t *transfer_op_flag)
{
	if (msg == NULL || data_transfer_handle == NULL ||
	    fru_table_handle == NULL || record_set_identifier == NULL ||
	    record_type == NULL || field_type == NULL ||
	    transfer_op_flag == NULL) {
		return PLDM_ERROR_INVALID_DATA;
	}

	if (payload_length !=
	    sizeof(struct pldm_get_fru_record_by_option_req)) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	struct pldm_get_fru_record_by_option_req *req =
	    (struct pldm_get_fru_record_by_option_req *)msg->payload;

	*data_transfer_handle = le32toh(req->data_transfer_handle);
	*fru_table_handle = le16toh(req->fru_table_handle);
	*record_set_identifier = le16toh(req->record_set_identifier);
	*record_type = req->record_type;
	*field_type = req->field_type;
	*transfer_op_flag = req->transfer_op_flag;
	return PLDM_SUCCESS;
}

int encode_get_fru_record_by_option_resp(uint8_t instance_id,
					 uint8_t completion_code,
					 uint32_t next_data_transfer_handle,
					 uint8_t transfer_flag,
					 const void *fru_structure_data,
					 size_t data_size, struct pldm_msg *msg,
					 size_t payload_length)
{
	if (msg == NULL || fru_structure_data == NULL) {
		return PLDM_ERROR_INVALID_DATA;
	}

	if (payload_length < PLDM_GET_FRU_RECORD_BY_OPTION_MIN_RESP_BYTES) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	struct pldm_header_info header = {0};
	header.instance = instance_id;
	header.msg_type = PLDM_RESPONSE;
	header.pldm_type = PLDM_FRU;
	header.command = PLDM_GET_FRU_RECORD_BY_OPTION;
	int rc = pack_pldm_header(&header, &(msg->hdr));
	if (rc != PLDM_SUCCESS) {
		return rc;
	}

	struct pldm_get_fru_record_by_option_resp *resp =
	    (struct pldm_get_fru_record_by_option_resp *)msg->payload;

	resp->completion_code = completion_code;
	resp->next_data_transfer_handle = htole32(next_data_transfer_handle);
	resp->transfer_flag = transfer_flag;

	if (completion_code != PLDM_SUCCESS) {
		return PLDM_SUCCESS;
	}

	if (payload_length !=
	    PLDM_GET_FRU_RECORD_BY_OPTION_MIN_RESP_BYTES + data_size) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	memcpy(resp->fru_structure_data, fru_structure_data, data_size);

	return PLDM_SUCCESS;
}

int decode_get_fru_record_by_option_resp(
    const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
    uint32_t *next_transfer_handle, uint8_t *transfer_flag,
    struct variable_field *fru_structure_data)
{
	if (msg == NULL || completion_code == NULL ||
	    next_transfer_handle == NULL || transfer_flag == NULL ||
	    fru_structure_data == NULL) {
		return PLDM_ERROR_INVALID_DATA;
	}

	*completion_code = msg->payload[0];
	if (PLDM_SUCCESS != *completion_code) {
		return PLDM_SUCCESS;
	}

	if (payload_length < PLDM_GET_FRU_RECORD_BY_OPTION_MIN_RESP_BYTES) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	struct pldm_get_fru_record_by_option_resp *resp =
	    (struct pldm_get_fru_record_by_option_resp *)msg->payload;

	*next_transfer_handle = le32toh(resp->next_data_transfer_handle);
	*transfer_flag = resp->transfer_flag;
	fru_structure_data->ptr = resp->fru_structure_data;
	fru_structure_data->length =
	    payload_length - PLDM_GET_FRU_RECORD_BY_OPTION_MIN_RESP_BYTES;

	return PLDM_SUCCESS;
}

int encode_get_fru_record_table_req(uint8_t instance_id,
				    uint32_t data_transfer_handle,
				    uint8_t transfer_operation_flag,
				    struct pldm_msg *msg, size_t payload_length)

{
	struct pldm_header_info header = {0};
	int rc = PLDM_ERROR_INVALID_DATA;

	header.msg_type = PLDM_REQUEST;
	header.instance = instance_id;
	header.pldm_type = PLDM_FRU;
	header.command = PLDM_GET_FRU_RECORD_TABLE;

	if (msg == NULL) {
		return rc;
	}
	if (payload_length != sizeof(struct pldm_get_fru_record_table_req)) {
		return PLDM_ERROR_INVALID_LENGTH;
	}
	if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
		return rc;
	}

	struct pldm_get_fru_record_table_req *req =
	    (struct pldm_get_fru_record_table_req *)msg->payload;
	req->data_transfer_handle = htole32(data_transfer_handle);
	req->transfer_operation_flag = transfer_operation_flag;

	return PLDM_SUCCESS;
}

int decode_get_fru_record_table_resp(
    const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
    uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
    uint8_t *fru_record_table_data, size_t *fru_record_table_length)
{
	if (msg == NULL || completion_code == NULL ||
	    next_data_transfer_handle == NULL || transfer_flag == NULL ||
	    fru_record_table_data == NULL || fru_record_table_length == NULL) {
		return PLDM_ERROR_INVALID_DATA;
	}

	*completion_code = msg->payload[0];
	if (PLDM_SUCCESS != *completion_code) {
		return PLDM_SUCCESS;
	}
	if (payload_length <= PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES) {
		return PLDM_ERROR_INVALID_LENGTH;
	}

	struct pldm_get_fru_record_table_resp *resp =
	    (struct pldm_get_fru_record_table_resp *)msg->payload;

	*next_data_transfer_handle = le32toh(resp->next_data_transfer_handle);
	*transfer_flag = resp->transfer_flag;
	memcpy(fru_record_table_data, resp->fru_record_table_data,
	       payload_length - PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES);
	*fru_record_table_length =
	    payload_length - PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES;

	return PLDM_SUCCESS;
}
