/*
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(modbus_raw, CONFIG_MODBUS_LOG_LEVEL);

#include <zephyr/kernel.h>
#include <zephyr/sys/byteorder.h>
#include <modbus_internal.h>

#define MODBUS_ADU_LENGTH_DEVIATION	2
#define MODBUS_RAW_MIN_MSG_SIZE		(MODBUS_RTU_MIN_MSG_SIZE - 2)
#define MODBUS_RAW_BUFFER_SIZE		(CONFIG_MODBUS_BUFFER_SIZE - 2)

int modbus_raw_rx_adu(struct modbus_context *ctx)
{
	if (ctx->rx_adu.length < MODBUS_RAW_MIN_MSG_SIZE ||
	    ctx->rx_adu.length > MODBUS_RAW_BUFFER_SIZE) {
		LOG_WRN("Frame length error");
		return -EMSGSIZE;
	}

	if (ctx->rx_adu.proto_id != MODBUS_ADU_PROTO_ID) {
		LOG_ERR("MODBUS protocol not supported");
		return -ENOTSUP;
	}

	return 0;
}

int modbus_raw_tx_adu(struct modbus_context *ctx)
{
	int iface = modbus_iface_get_by_ctx(ctx);

	if (ctx->mode != MODBUS_MODE_RAW) {
		return -ENOTSUP;
	}

	if (iface < 0) {
		return -ENODEV;
	}

	ctx->rawcb.raw_tx_cb(iface, &ctx->tx_adu, ctx->rawcb.user_data);

	return 0;
}

int modbus_raw_submit_rx(const int iface, const struct modbus_adu *adu)
{
	struct modbus_context *ctx;

	ctx = modbus_get_context(iface);

	if (ctx == NULL) {
		LOG_ERR("Interface not available");
		return -ENODEV;
	}

	if (ctx->mode != MODBUS_MODE_RAW) {
		LOG_ERR("Interface not in RAW mode");
		return -ENOTSUP;
	}

	ctx->rx_adu.trans_id = adu->trans_id;
	ctx->rx_adu.proto_id = adu->proto_id;
	ctx->rx_adu.length = adu->length;
	ctx->rx_adu.unit_id = adu->unit_id;
	ctx->rx_adu.fc = adu->fc;
	memcpy(ctx->rx_adu.data, adu->data,
	       MIN(adu->length, sizeof(ctx->rx_adu.data)));
	k_work_submit(&ctx->server_work);

	return 0;
}

void modbus_raw_put_header(const struct modbus_adu *adu, uint8_t *header)
{
	uint16_t length = MIN(adu->length, CONFIG_MODBUS_BUFFER_SIZE);

	sys_put_be16(adu->trans_id, &header[0]);
	sys_put_be16(adu->proto_id, &header[2]);
	sys_put_be16(length + MODBUS_ADU_LENGTH_DEVIATION, &header[4]);
	header[6] = adu->unit_id;
	header[7] = adu->fc;
}

void modbus_raw_get_header(struct modbus_adu *adu, const uint8_t *header)
{
	adu->trans_id = sys_get_be16(&header[0]);
	adu->proto_id = sys_get_be16(&header[2]);
	adu->length = MIN(sys_get_be16(&header[4]), CONFIG_MODBUS_BUFFER_SIZE);
	adu->unit_id = header[6];
	adu->fc = header[7];

	if (adu->length >= MODBUS_ADU_LENGTH_DEVIATION) {
		adu->length -= MODBUS_ADU_LENGTH_DEVIATION;
	}
}

static void modbus_set_exception(struct modbus_adu *adu,
				 const uint8_t excep_code)
{
	const uint8_t excep_bit = BIT(7);

	adu->fc |= excep_bit;
	adu->data[0] = excep_code;
	adu->length = 1;
}

void modbus_raw_set_server_failure(struct modbus_adu *adu)
{
	const uint8_t excep_bit = BIT(7);

	adu->fc |= excep_bit;
	adu->data[0] = MODBUS_EXC_SERVER_DEVICE_FAILURE;
	adu->length = 1;
}

int modbus_raw_backend_txn(const int iface, struct modbus_adu *adu)
{
	struct modbus_context *ctx;
	int err;

	ctx = modbus_get_context(iface);
	if (ctx == NULL) {
		LOG_ERR("Interface %d not available", iface);
		modbus_set_exception(adu, MODBUS_EXC_GW_PATH_UNAVAILABLE);
		return -ENODEV;
	}

	/*
	 * This is currently only possible over serial line
	 * since no other medium is directly supported.
	 */
	if (ctx->client == false ||
	    (ctx->mode != MODBUS_MODE_RTU && ctx->mode != MODBUS_MODE_ASCII)) {
		LOG_ERR("Interface %d has wrong configuration", iface);
		modbus_set_exception(adu, MODBUS_EXC_GW_PATH_UNAVAILABLE);
		return -ENOTSUP;
	}

	LOG_DBG("Use backend interface %d", iface);
	memcpy(&ctx->tx_adu, adu, sizeof(struct modbus_adu));
	err = modbus_tx_wait_rx_adu(ctx);

	if (err == 0) {
		/*
		 * Serial line does not use transaction and protocol IDs.
		 * Temporarily store transaction and protocol IDs, and write it
		 * back if the transfer was successful.
		 */
		uint16_t trans_id = adu->trans_id;
		uint16_t proto_id = adu->proto_id;

		memcpy(adu, &ctx->rx_adu, sizeof(struct modbus_adu));
		adu->trans_id = trans_id;
		adu->proto_id = proto_id;
	} else {
		modbus_set_exception(adu, MODBUS_EXC_GW_TARGET_FAILED_TO_RESP);
	}

	return err;
}

int modbus_raw_init(struct modbus_context *ctx,
		    struct modbus_iface_param param)
{
	if (ctx->mode != MODBUS_MODE_RAW) {
		return -ENOTSUP;
	}

	ctx->rawcb.raw_tx_cb = param.rawcb.raw_tx_cb;
	ctx->rawcb.user_data = param.rawcb.user_data;

	return 0;
}

void modbus_raw_disable(struct modbus_context *ctx)
{
}
