/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
#include <libpldm/oem/meta/file_io.h>
#include <endian.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "api.h"
#include "msgbuf.h"
#include "dsp/base.h"

LIBPLDM_ABI_TESTING
void *pldm_oem_meta_file_io_write_req_data(
	struct pldm_oem_meta_file_io_write_req *req)
{
	return req->data;
}

LIBPLDM_ABI_TESTING
int decode_oem_meta_file_io_write_req(
	const struct pldm_msg *msg, size_t payload_length,
	struct pldm_oem_meta_file_io_write_req *req, size_t req_length)
{
	struct pldm_msgbuf _buf;
	struct pldm_msgbuf *buf = &_buf;
	int rc;

	if (msg == NULL || req == NULL) {
		return -EINVAL;
	}

	if (req_length < sizeof(*req)) {
		return -EINVAL;
	}

	rc = pldm_msgbuf_init_errno(buf,
				    PLDM_OEM_META_FILE_IO_WRITE_REQ_MIN_LENGTH,
				    msg->payload, payload_length);
	if (rc) {
		return rc;
	}

	pldm_msgbuf_extract(buf, req->handle);
	rc = pldm_msgbuf_extract(buf, req->length);
	if (rc) {
		return rc;
	}

	rc = pldm_msgbuf_extract_array(buf, req->length, req->data,
				       req_length - sizeof(*req));
	if (rc) {
		return rc;
	}

	return pldm_msgbuf_destroy_consumed(buf);
}

LIBPLDM_ABI_DEPRECATED
int decode_oem_meta_file_io_req(const struct pldm_msg *msg,
				size_t payload_length, uint8_t *file_handle,
				uint32_t *length, uint8_t *data)
{
	struct pldm_oem_meta_file_io_write_req *request_msg;
	size_t request_msg_len;
	int rc;

	if (msg == NULL || file_handle == NULL || length == NULL ||
	    data == NULL) {
		return pldm_xlate_errno(-EINVAL);
	}

	request_msg_len = sizeof(*request_msg) + payload_length;
	request_msg = malloc(request_msg_len);

	rc = decode_oem_meta_file_io_write_req(msg, payload_length, request_msg,
					       request_msg_len);
	if (rc < 0) {
		free(request_msg);
		return pldm_xlate_errno(rc);
	}

	*file_handle = request_msg->handle;
	*length = request_msg->length;

	/* NOTE: Unsafe, memory safety is not possible due to API constraints. */
	memcpy(data, request_msg->data, request_msg->length);

	free(request_msg);

	return 0;
}

LIBPLDM_ABI_TESTING
int decode_oem_meta_file_io_read_req(const struct pldm_msg *msg,
				     size_t payload_length,
				     struct pldm_oem_meta_file_io_read_req *req)
{
	struct pldm_msgbuf _buf;
	struct pldm_msgbuf *buf = &_buf;

	if (msg == NULL || req == NULL) {
		return -EINVAL;
	}

	if (req->version > sizeof(struct pldm_oem_meta_file_io_read_req)) {
		return -E2BIG;
	}

	int rc = pldm_msgbuf_init_errno(
		buf, PLDM_OEM_META_FILE_IO_READ_REQ_MIN_LENGTH, msg->payload,
		payload_length);
	if (rc) {
		return rc;
	}

	pldm_msgbuf_extract(buf, req->handle);
	rc = pldm_msgbuf_extract(buf, req->option);
	if (rc) {
		return rc;
	}

	rc = pldm_msgbuf_extract(buf, req->length);
	if (rc) {
		return rc;
	}

	switch (req->option) {
	case PLDM_OEM_META_FILE_IO_READ_ATTR:
		if (req->length != 0) {
			return -EPROTO;
		}
		break;
	case PLDM_OEM_META_FILE_IO_READ_DATA:
		pldm_msgbuf_extract(buf, req->info.data.transferFlag);
		pldm_msgbuf_extract(buf, req->info.data.offset);
		break;
	default:
		return -EPROTO;
	}

	return pldm_msgbuf_destroy_consumed(buf);
}

LIBPLDM_ABI_TESTING
void *pldm_oem_meta_file_io_read_resp_data(
	struct pldm_oem_meta_file_io_read_resp *resp)
{
	return resp->data;
}

LIBPLDM_ABI_TESTING
int encode_oem_meta_file_io_read_resp(
	uint8_t instance_id, struct pldm_oem_meta_file_io_read_resp *resp,
	size_t resp_len, struct pldm_msg *responseMsg, size_t payload_length)
{
	int rc;
	struct pldm_msgbuf _buf;
	struct pldm_msgbuf *buf = &_buf;
	struct pldm_header_info header = { 0 };

	if (resp == NULL || responseMsg == NULL) {
		return -EINVAL;
	}

	if (resp_len < sizeof(*resp)) {
		return -EINVAL;
	}

	if (resp->version > sizeof(*resp)) {
		return -E2BIG;
	}

	header.instance = instance_id;
	header.msg_type = PLDM_RESPONSE;
	header.pldm_type = PLDM_OEM;
	header.command = PLDM_OEM_META_FILE_IO_CMD_READ_FILE;
	rc = pack_pldm_header_errno(&header, &(responseMsg->hdr));
	if (rc) {
		return rc;
	}

	rc = pldm_msgbuf_init_errno(buf,
				    PLDM_OEM_META_FILE_IO_READ_RESP_MIN_SIZE,
				    responseMsg->payload, payload_length);
	if (rc) {
		return rc;
	}

	pldm_msgbuf_insert(buf, resp->completion_code);
	pldm_msgbuf_insert(buf, resp->handle);
	pldm_msgbuf_insert(buf, resp->option);
	pldm_msgbuf_insert(buf, resp->length);

	switch (resp->option) {
	case PLDM_OEM_META_FILE_IO_READ_ATTR:
		pldm_msgbuf_insert(buf, resp->info.attr.size);
		pldm_msgbuf_insert(buf, resp->info.attr.crc32);
		break;
	case PLDM_OEM_META_FILE_IO_READ_DATA:
		pldm_msgbuf_insert(buf, resp->info.data.transferFlag);
		pldm_msgbuf_insert(buf, resp->info.data.offset);
		rc = pldm_msgbuf_insert_array_uint8(buf, resp->length,
						    resp->data,
						    resp_len - sizeof(*resp));
		if (rc) {
			return rc;
		}
		break;
	default:
		return -EPROTO;
	}

	return pldm_msgbuf_destroy(buf);
}
