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

#include <errno.h>
#include <zephyr/device.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/devicetree.h>
#include "usbh_internal.h"

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(uhs, CONFIG_USBH_LOG_LEVEL);

static K_KERNEL_STACK_DEFINE(usbh_stack, CONFIG_USBH_STACK_SIZE);
static struct k_thread usbh_thread_data;

/* TODO */
static struct usbh_class_data *class_data;

K_MSGQ_DEFINE(usbh_msgq, sizeof(struct uhc_event),
	      CONFIG_USBH_MAX_UHC_MSG, sizeof(uint32_t));

static int usbh_event_carrier(const struct device *dev,
			      const struct uhc_event *const event)
{
	return k_msgq_put(&usbh_msgq, event, K_NO_WAIT);
}

static int event_ep_request(struct usbh_contex *const ctx,
			    struct uhc_event *const event)
{
	struct uhc_transfer *xfer = event->xfer;
	const struct device *dev = ctx->dev;

	if (class_data && class_data->request) {
		return class_data->request(ctx, event->xfer, event->status);
	}

	while (!k_fifo_is_empty(&xfer->done)) {
		struct net_buf *buf;

		buf = net_buf_get(&xfer->done, K_NO_WAIT);
		if (buf) {
			LOG_HEXDUMP_INF(buf->data, buf->len, "buf");
			uhc_xfer_buf_free(dev, buf);
		}
	}

	return uhc_xfer_free(dev, xfer);
}

static int ALWAYS_INLINE usbh_event_handler(struct usbh_contex *const ctx,
					    struct uhc_event *const event)
{
	int ret = 0;

	switch (event->type) {
	case UHC_EVT_DEV_CONNECTED_LS:
	case UHC_EVT_DEV_CONNECTED_FS:
	case UHC_EVT_DEV_CONNECTED_HS:
		LOG_DBG("Device connected event");
		if (class_data && class_data->connected) {
			ret = class_data->connected(ctx);
		}
		break;
	case UHC_EVT_DEV_REMOVED:
		LOG_DBG("Device removed event");
		if (class_data && class_data->removed) {
			ret = class_data->removed(ctx);
		}
		break;
	case UHC_EVT_RESETED:
		LOG_DBG("Bus reseted");
		/* TODO */
		if (class_data && class_data->removed) {
			ret = class_data->removed(ctx);
		}
		break;
	case UHC_EVT_SUSPENDED:
		LOG_DBG("Bus suspended");
		if (class_data && class_data->suspended) {
			ret = class_data->suspended(ctx);
		}
		break;
	case UHC_EVT_RESUMED:
		LOG_DBG("Bus resumed");
		if (class_data && class_data->resumed) {
			ret = class_data->resumed(ctx);
		}
		break;
	case UHC_EVT_RWUP:
		LOG_DBG("RWUP event");
		if (class_data && class_data->rwup) {
			ret = class_data->rwup(ctx);
		}
		break;
	case UHC_EVT_EP_REQUEST:
		event_ep_request(ctx, event);
		break;
	case UHC_EVT_ERROR:
		LOG_DBG("Error event");
		break;
	default:
		break;
	};

	return ret;
}

static void usbh_thread(const struct device *dev)
{
	struct uhc_event event;

	while (true) {
		k_msgq_get(&usbh_msgq, &event, K_FOREVER);

		STRUCT_SECTION_FOREACH(usbh_contex, uhs_ctx) {
			if (uhs_ctx->dev == event.dev) {
				usbh_event_handler(uhs_ctx, &event);
			}
		}
	}
}

int usbh_init_device_intl(struct usbh_contex *const uhs_ctx)
{
	int ret;

	ret = uhc_init(uhs_ctx->dev, usbh_event_carrier);
	if (ret != 0) {
		LOG_ERR("Failed to init device driver");
		return ret;
	}

	STRUCT_SECTION_FOREACH(usbh_class_data, cdata) {
		LOG_DBG("class data %p", cdata);
		/* TODO */
		class_data = cdata;
		break;
	}

	return 0;
}

static int uhs_pre_init(const struct device *unused)
{
	k_thread_create(&usbh_thread_data, usbh_stack,
			K_KERNEL_STACK_SIZEOF(usbh_stack),
			(k_thread_entry_t)usbh_thread,
			NULL, NULL, NULL,
			K_PRIO_COOP(9), 0, K_NO_WAIT);

	k_thread_name_set(&usbh_thread_data, "usbh");

	return 0;
}

SYS_INIT(uhs_pre_init, POST_KERNEL, CONFIG_USBH_INIT_PRIO);
