/*
 * Copyright (c) 2024 CogniPilot Foundation
 * Copyright (c) 2024 NXP Semiconductors
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT futaba_sbus

#include <zephyr/device.h>
#include <zephyr/input/input.h>
#include <zephyr/irq.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/time_units.h>
#include <zephyr/sys_clock.h>
#include <zephyr/drivers/uart.h>

LOG_MODULE_REGISTER(futaba_sbus, CONFIG_INPUT_LOG_LEVEL);

/* Driver config */
struct sbus_input_channel {
	uint32_t sbus_channel;
	uint32_t type;
	uint32_t zephyr_code;
};

const struct uart_config uart_cfg_sbus = {
	.baudrate = 100000,
	.parity = UART_CFG_PARITY_EVEN,
	.stop_bits = UART_CFG_STOP_BITS_2,
	.data_bits = UART_CFG_DATA_BITS_8,
	.flow_ctrl = UART_CFG_FLOW_CTRL_NONE
};

struct input_sbus_config {
	uint8_t num_channels;
	const struct sbus_input_channel *channel_info;
	const struct device *uart_dev;
	uart_irq_callback_user_data_t cb;
};

#define SBUS_FRAME_LEN 25
#define SBUS_HEADER    0x0F
#define SBUS_FOOTER    0x00

#define SBUS_SERVO_LEN     22
#define SBUS_SERVO_CH_MASK 0x7FF

#define SBUS_BYTE24_IDX        23
#define SBUS_BYTE24_CH17       0x01
#define SBUS_BYTE24_CH18       0x02
#define SBUS_BYTE24_FRAME_LOST 0x04
#define SBUS_BYTE24_FAILSAFE   0x08

#define SBUS_TRANSMISSION_TIME_MS  4  /* Max transmission of a single SBUS frame */
#define SBUS_INTERFRAME_SPACING_MS 20 /* Max spacing between SBUS frames */
#define SBUS_CHANNEL_COUNT         16

#define REPORT_FILTER      CONFIG_INPUT_SBUS_REPORT_FILTER
#define CHANNEL_VALUE_ZERO CONFIG_INPUT_SBUS_CHANNEL_VALUE_ZERO
#define CHANNEL_VALUE_ONE  CONFIG_INPUT_SBUS_CHANNEL_VALUE_ONE

struct input_sbus_data {
	struct k_thread thread;
	struct k_sem report_lock;

	uint16_t xfer_bytes;
	uint8_t rd_data[SBUS_FRAME_LEN];
	uint8_t sbus_frame[SBUS_FRAME_LEN];
	bool partial_sync;
	bool in_sync;
	uint32_t last_rx_time;

	uint16_t last_reported_value[SBUS_CHANNEL_COUNT];
	int8_t channel_mapping[SBUS_CHANNEL_COUNT];

	K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_INPUT_SBUS_THREAD_STACK_SIZE);
};

static void input_sbus_report(const struct device *dev, unsigned int sbus_channel,
			      unsigned int value)
{
	const struct input_sbus_config *const config = dev->config;
	struct input_sbus_data *const data = dev->data;

	int channel = data->channel_mapping[sbus_channel];

	/* Not Mapped */
	if (channel == -1) {
		return;
	}

	if (value >= (data->last_reported_value[channel] + REPORT_FILTER) ||
	    value <= (data->last_reported_value[channel] - REPORT_FILTER)) {
		switch (config->channel_info[channel].type) {
		case INPUT_EV_ABS:
		case INPUT_EV_MSC:
			input_report(dev, config->channel_info[channel].type,
				     config->channel_info[channel].zephyr_code, value, false,
				     K_FOREVER);
			break;

		default:
			if (value > CHANNEL_VALUE_ONE) {
				input_report_key(dev, config->channel_info[channel].zephyr_code, 1,
						 false, K_FOREVER);
			} else if (value < CHANNEL_VALUE_ZERO) {
				input_report_key(dev, config->channel_info[channel].zephyr_code, 0,
						 false, K_FOREVER);
			}
		}
		data->last_reported_value[channel] = value;
	}
}

static void input_sbus_input_report_thread(const struct device *dev, void *dummy2, void *dummy3)
{
	struct input_sbus_data *const data = dev->data;

	ARG_UNUSED(dummy2);
	ARG_UNUSED(dummy3);

	uint8_t i, channel;
	uint8_t *sbus_channel_data = &data->sbus_frame[1]; /* Omit header */
	uint32_t value;
	int bits_read;
	unsigned int key;
	int ret;
	bool connected_reported = false;

	while (true) {
		if (!data->in_sync) {
			k_sem_take(&data->report_lock, K_FOREVER);
			if (data->in_sync) {
				LOG_DBG("SBUS receiver connected");
			} else {
				continue;
			}
		} else {
			ret = k_sem_take(&data->report_lock, K_MSEC(SBUS_INTERFRAME_SPACING_MS));
			if (ret == -EBUSY) {
				continue;
			} else if (ret < 0 || !data->in_sync) {
				/* We've lost sync with the UART receiver */
				key = irq_lock();

				data->partial_sync = false;
				data->in_sync = false;
				data->xfer_bytes = 0;
				irq_unlock(key);

				connected_reported = false;
				LOG_DBG("SBUS receiver connection lost");

				/* Report connection lost */
				continue;
			}
		}

		if (connected_reported &&
		    data->sbus_frame[SBUS_BYTE24_IDX] & SBUS_BYTE24_FRAME_LOST) {
			LOG_DBG("SBUS controller connection lost");
			connected_reported = false;
		} else if (!connected_reported &&
			   !(data->sbus_frame[SBUS_BYTE24_IDX] & SBUS_BYTE24_FRAME_LOST)) {
			LOG_DBG("SBUS controller connected");
			connected_reported = true;
		}

		/* Parse the data */
		channel = 0;
		value = 0;
		bits_read = 0;

		for (i = 0; i < SBUS_SERVO_LEN; i++) {
			/* Read the next byte */
			unsigned char byte = sbus_channel_data[i];

			/* Extract bits and construct the 11-bit value */
			value |= byte << bits_read;
			bits_read += 8;

			/* Check if we've read enough bits to form a full 11-bit value */
			while (bits_read >= 11) {
				input_sbus_report(dev, channel, value & SBUS_SERVO_CH_MASK);

				/* Shift right to prepare for the next 11 bits */
				value >>= 11;
				bits_read -= 11;
				channel++;
			}
		}

#ifdef CONFIG_INPUT_SBUS_SEND_SYNC
		input_report(dev, 0, 0, 0, true, K_FOREVER);
#endif
	}
}

static void sbus_resync(const struct device *uart_dev, struct input_sbus_data *const data)
{
	uint8_t *rd_data = data->rd_data;

	if (data->partial_sync) {
		data->xfer_bytes += uart_fifo_read(uart_dev, &rd_data[data->xfer_bytes],
						   SBUS_FRAME_LEN - data->xfer_bytes);
		if (data->xfer_bytes == SBUS_FRAME_LEN) {
			/* Transfer took longer then 4ms probably faulty */
			if (k_uptime_get_32() - data->last_rx_time > SBUS_TRANSMISSION_TIME_MS) {
				data->xfer_bytes = 0;
				data->partial_sync = false;
			} else if (rd_data[0] == SBUS_HEADER &&
				   rd_data[SBUS_FRAME_LEN - 1] == SBUS_FOOTER) {
				data->in_sync = true;
			} else {
				/* Dummy read to clear fifo */
				uart_fifo_read(uart_dev, &rd_data[0], 1);
				data->xfer_bytes = 0;
				data->partial_sync = false;
			}
		}
	} else {
		if (uart_fifo_read(uart_dev, &rd_data[0], 1) == 1) {
			if (rd_data[0] == SBUS_HEADER) {
				data->partial_sync = true;
				data->xfer_bytes = 1;
				data->last_rx_time = k_uptime_get_32();
			}
		}
	}
}

static void sbus_uart_isr(const struct device *uart_dev, void *user_data)
{
	const struct device *dev = user_data;
	struct input_sbus_data *const data = dev->data;
	uint8_t *rd_data = data->rd_data;

	if (uart_dev == NULL) {
		LOG_DBG("UART device is NULL");
		return;
	}

	if (!uart_irq_update(uart_dev)) {
		LOG_DBG("Unable to start processing interrupts");
		return;
	}

	while (uart_irq_rx_ready(uart_dev) && data->xfer_bytes < SBUS_FRAME_LEN) {
		if (data->in_sync) {
			if (data->xfer_bytes == 0) {
				data->last_rx_time = k_uptime_get_32();
			}
			data->xfer_bytes += uart_fifo_read(uart_dev, &rd_data[data->xfer_bytes],
							   SBUS_FRAME_LEN - data->xfer_bytes);
		} else {
			sbus_resync(uart_dev, data);
		}
	}

	if (data->in_sync && (k_uptime_get_32() - data->last_rx_time >
	    SBUS_INTERFRAME_SPACING_MS)) {
		data->partial_sync = false;
		data->in_sync = false;
		data->xfer_bytes = 0;
		k_sem_give(&data->report_lock);
	} else if (data->in_sync && data->xfer_bytes == SBUS_FRAME_LEN) {
		data->xfer_bytes = 0;

		if (rd_data[0] == SBUS_HEADER && rd_data[SBUS_FRAME_LEN - 1] == SBUS_FOOTER) {
			memcpy(data->sbus_frame, rd_data, SBUS_FRAME_LEN);
			k_sem_give(&data->report_lock);
		} else {
			data->partial_sync = false;
			data->in_sync = false;
		}
	}
}

/*
 * @brief Initialize sbus driver
 */
static int input_sbus_init(const struct device *dev)
{
	const struct input_sbus_config *const config = dev->config;
	struct input_sbus_data *const data = dev->data;
	int i, ret;

	uart_irq_rx_disable(config->uart_dev);
	uart_irq_tx_disable(config->uart_dev);

	LOG_DBG("Initializing SBUS driver");

	for (i = 0; i < SBUS_CHANNEL_COUNT; i++) {
		data->last_reported_value[i] = 0;
		data->channel_mapping[i] = -1;
	}

	data->xfer_bytes = 0;
	data->in_sync = false;
	data->partial_sync = false;
	data->last_rx_time = 0;

	for (i = 0; i < config->num_channels; i++) {
		data->channel_mapping[config->channel_info[i].sbus_channel - 1] = i;
	}

	ret = uart_configure(config->uart_dev, &uart_cfg_sbus);
	if (ret < 0) {
		LOG_ERR("Unable to configure UART port: %d", ret);
		return ret;
	}

	ret = uart_irq_callback_user_data_set(config->uart_dev, config->cb, (void *)dev);
	if (ret < 0) {
		if (ret == -ENOTSUP) {
			LOG_ERR("Interrupt-driven UART API support not enabled");
		} else if (ret == -ENOSYS) {
			LOG_ERR("UART device does not support interrupt-driven API");
		} else {
			LOG_ERR("Error setting UART callback: %d", ret);
		}
		return ret;
	}

	k_sem_init(&data->report_lock, 0, 1);

	uart_irq_rx_enable(config->uart_dev);

	k_thread_create(&data->thread, data->thread_stack,
			K_KERNEL_STACK_SIZEOF(data->thread_stack),
			(k_thread_entry_t)input_sbus_input_report_thread, (void *)dev, NULL, NULL,
			CONFIG_INPUT_SBUS_THREAD_PRIORITY, 0, K_NO_WAIT);

	k_thread_name_set(&data->thread, dev->name);

	return ret;
}

#define INPUT_CHANNEL_CHECK(input_channel_id)                                                      \
	BUILD_ASSERT(IN_RANGE(DT_PROP(input_channel_id, channel), 1, 16),                          \
		     "invalid channel number");                                                    \
	BUILD_ASSERT(DT_PROP(input_channel_id, type) == INPUT_EV_ABS ||                            \
			     DT_PROP(input_channel_id, type) == INPUT_EV_KEY ||                    \
			     DT_PROP(input_channel_id, type) == INPUT_EV_MSC,                      \
		     "invalid channel type");

#define SBUS_INPUT_CHANNEL_INITIALIZER(input_channel_id)                                           \
	{                                                                                          \
		.sbus_channel = DT_PROP(input_channel_id, channel),                                \
		.type = DT_PROP(input_channel_id, type),                                           \
		.zephyr_code = DT_PROP(input_channel_id, zephyr_code),                             \
	},

#define INPUT_SBUS_INIT(n)                                                                         \
                                                                                                   \
	static const struct sbus_input_channel input_##n[] = {                                     \
		DT_INST_FOREACH_CHILD(n, SBUS_INPUT_CHANNEL_INITIALIZER)                           \
	};                                                                                         \
	DT_INST_FOREACH_CHILD(n, INPUT_CHANNEL_CHECK)                                              \
                                                                                                   \
	static struct input_sbus_data sbus_data_##n;                                               \
                                                                                                   \
	static const struct input_sbus_config sbus_cfg_##n = {                                     \
		.channel_info = input_##n,                                                         \
		.uart_dev = DEVICE_DT_GET(DT_INST_BUS(n)),                                         \
		.num_channels = ARRAY_SIZE(input_##n),                                             \
		.cb = sbus_uart_isr,                                                               \
	};                                                                                         \
                                                                                                   \
	DEVICE_DT_INST_DEFINE(n, input_sbus_init, NULL, &sbus_data_##n, &sbus_cfg_##n,             \
			      POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, NULL);

DT_INST_FOREACH_STATUS_OKAY(INPUT_SBUS_INIT)
