/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/ztest.h>
#include <zephyr/tc_util.h>

#include <zephyr/sys/byteorder.h>
#include <zephyr/usb/usb_device.h>
#include <usb_descriptor.h>
#include <zephyr/sys/iterable_sections.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(test_main, LOG_LEVEL_DBG);

#ifdef CONFIG_USB_COMPOSITE_DEVICE
#error Do not use composite configuration
#endif

/* Linker-defined symbols bound the USB descriptor structs */
extern struct usb_desc_header __usb_descriptor_start[];
extern struct usb_desc_header __usb_descriptor_end[];
extern struct usb_cfg_data _usb_cfg_data_list_start[];
extern struct usb_cfg_data _usb_cfg_data_list_end[];

uint8_t *usb_get_device_descriptor(void);

struct usb_test_config {
	struct usb_if_descriptor if0;
	struct usb_ep_descriptor if0_out_ep;
	struct usb_ep_descriptor if0_in1_ep;
	struct usb_ep_descriptor if0_in2_ep;
} __packed;

#if defined(CONFIG_USB_DC_HAS_HS_SUPPORT)
#define TEST_BULK_EP_MPS		512
#else
#define TEST_BULK_EP_MPS		64
#endif

#define TEST_DESCRIPTOR_TABLE_SPAN	157

#define INITIALIZER_IF							\
	{								\
		.bLength = sizeof(struct usb_if_descriptor),		\
		.bDescriptorType = USB_DESC_INTERFACE,			\
		.bInterfaceNumber = 0,					\
		.bAlternateSetting = 0,					\
		.bNumEndpoints = 3,					\
		.bInterfaceClass = USB_BCC_VENDOR,			\
		.bInterfaceSubClass = 0,				\
		.bInterfaceProtocol = 0,				\
		.iInterface = 0,					\
	}

#define INITIALIZER_IF_EP(addr, attr, mps)				\
	{								\
		.bLength = sizeof(struct usb_ep_descriptor),		\
		.bDescriptorType = USB_DESC_ENDPOINT,			\
		.bEndpointAddress = addr,				\
		.bmAttributes = attr,					\
		.wMaxPacketSize = sys_cpu_to_le16(mps),			\
		.bInterval = 0x00,					\
	}


#define DEFINE_TEST_DESC(x, _)						\
	USBD_CLASS_DESCR_DEFINE(primary, x)				\
	struct usb_test_config test_cfg_##x = {				\
	.if0 = INITIALIZER_IF,						\
	.if0_out_ep = INITIALIZER_IF_EP(AUTO_EP_OUT,			\
					USB_DC_EP_BULK,			\
					TEST_BULK_EP_MPS),		\
	.if0_in1_ep = INITIALIZER_IF_EP(AUTO_EP_IN,			\
					USB_DC_EP_BULK,			\
					TEST_BULK_EP_MPS),		\
	.if0_in2_ep = INITIALIZER_IF_EP(AUTO_EP_IN,			\
					USB_DC_EP_BULK,			\
					TEST_BULK_EP_MPS),		\
	}

#define INITIALIZER_EP_DATA(cb, addr)					\
	{								\
		.ep_cb = cb,						\
		.ep_addr = addr,					\
	}

#define DEFINE_TEST_EP_CFG(x, _)				\
	static struct usb_ep_cfg_data ep_cfg_##x[] = {		\
		INITIALIZER_EP_DATA(NULL, AUTO_EP_OUT),		\
		INITIALIZER_EP_DATA(NULL, AUTO_EP_IN),		\
		INITIALIZER_EP_DATA(NULL, AUTO_EP_IN),		\
	}

#define DEFINE_TEST_CFG_DATA(x, _)				\
	USBD_DEFINE_CFG_DATA(test_config_##x) = {		\
	.usb_device_description = NULL,				\
	.interface_config = interface_config,			\
	.interface_descriptor = &test_cfg_##x.if0,		\
	.cb_usb_status = NULL,					\
	.interface = {						\
		.class_handler = NULL,				\
		.custom_handler = NULL,				\
		.vendor_handler = NULL,				\
	},							\
	.num_endpoints = ARRAY_SIZE(ep_cfg_##x),		\
	.endpoint = ep_cfg_##x,					\
	}

#define NUM_INSTANCES 2

static void interface_config(struct usb_desc_header *head,
			     uint8_t iface_num)
{
	struct usb_if_descriptor *if_desc = (struct usb_if_descriptor *)head;

	LOG_DBG("head %p iface_num %u", head, iface_num);

	if_desc->bInterfaceNumber = iface_num;
}

LISTIFY(NUM_INSTANCES, DEFINE_TEST_DESC, (;), _);
LISTIFY(NUM_INSTANCES, DEFINE_TEST_EP_CFG, (;), _);
LISTIFY(NUM_INSTANCES, DEFINE_TEST_CFG_DATA, (;), _);

static struct usb_cfg_data *usb_get_cfg_data(struct usb_if_descriptor *iface)
{
	STRUCT_SECTION_FOREACH(usb_cfg_data, cfg_data) {
		if (cfg_data->interface_descriptor == iface) {
			return cfg_data;
		}
	}

	return NULL;
}

static bool find_cfg_data_ep(const struct usb_ep_descriptor * const ep_descr,
			     const struct usb_cfg_data * const cfg_data,
			     uint8_t ep_count)
{
	for (int i = 0; i < cfg_data->num_endpoints; i++) {
		if (cfg_data->endpoint[i].ep_addr ==
				ep_descr->bEndpointAddress) {
			LOG_DBG("found ep[%d] %x", i,
				ep_descr->bEndpointAddress);

			if (ep_count != i) {
				LOG_ERR("EPs are assigned in wrong order");
				return false;
			}

			return true;
		}
	}

	return false;
}

static void check_endpoint_allocation(struct usb_desc_header *head)
{
	struct usb_cfg_data *cfg_data = NULL;
	static uint8_t interfaces;
	uint8_t ep_count = 0;

	while (head->bLength != 0) {
		if (head->bDescriptorType == USB_DESC_INTERFACE) {
			struct usb_if_descriptor *if_descr = (void *)head;

			ep_count = 0;

			LOG_DBG("iface %u", if_descr->bInterfaceNumber);

			/* Check that interfaces get correct numbers */
			zassert_equal(if_descr->bInterfaceNumber, interfaces,
				      "Interfaces numbering failed");

			interfaces++;

			cfg_data = usb_get_cfg_data(if_descr);
			zassert_not_null(cfg_data, "Check available cfg data");
		}

		if (head->bDescriptorType == USB_DESC_ENDPOINT) {
			struct usb_ep_descriptor *ep_descr =
				(struct usb_ep_descriptor *)head;

			/* Check that we get iface desc before */
			zassert_not_null(cfg_data, "Check available cfg data");

			zassert_true(find_cfg_data_ep(ep_descr, cfg_data,
						      ep_count),
				     "Check endpoint config in cfg_data");
			ep_count++;
		}

		head = (struct usb_desc_header *)((uint8_t *)head + head->bLength);
	}
}

/* Determine the number of bytes spanned between two linker-defined
 * symbols that are normally interpreted as pointers.
 */
#define SYMBOL_SPAN(_ep, _sp) (int)(intptr_t)((uintptr_t)(_ep) - (uintptr_t)(_sp))

ZTEST(desc_sections, test_desc_sections)
{
	struct usb_desc_header *head;

	TC_PRINT("__usb_descriptor_start %p\n", __usb_descriptor_start);
	TC_PRINT("__usb_descriptor_end %p\n",  __usb_descriptor_end);
	TC_PRINT("USB Descriptor table span %d\n",
		 SYMBOL_SPAN(__usb_descriptor_end, __usb_descriptor_start));

	TC_PRINT("_usb_cfg_data_list_start %p\n", _usb_cfg_data_list_start);
	TC_PRINT("_usb_cfg_data_list_end %p\n", _usb_cfg_data_list_end);
	TC_PRINT("USB Configuration data span %d\n",
		 SYMBOL_SPAN(_usb_cfg_data_list_end, _usb_cfg_data_list_start));

	TC_PRINT("sizeof usb_cfg_data %zu\n", sizeof(struct usb_cfg_data));

	LOG_DBG("Starting logs");

	LOG_HEXDUMP_DBG((uint8_t *)__usb_descriptor_start,
			SYMBOL_SPAN(__usb_descriptor_end, __usb_descriptor_start),
			"USB Descriptor table section");

	LOG_HEXDUMP_DBG((uint8_t *)_usb_cfg_data_list_start,
			SYMBOL_SPAN(_usb_cfg_data_list_end, _usb_cfg_data_list_start),
			"USB Configuration structures section");

	head = (struct usb_desc_header *)__usb_descriptor_start;
	zassert_not_null(head, NULL);

	zassert_equal(SYMBOL_SPAN(__usb_descriptor_end, __usb_descriptor_start),
		      TEST_DESCRIPTOR_TABLE_SPAN, NULL);

	/* Calculate number of structures */
	zassert_equal(_usb_cfg_data_list_end - _usb_cfg_data_list_start,
		      NUM_INSTANCES, NULL);
	zassert_equal(SYMBOL_SPAN(_usb_cfg_data_list_end, _usb_cfg_data_list_start),
		      NUM_INSTANCES * sizeof(struct usb_cfg_data), NULL);

	check_endpoint_allocation(head);
}

/*test case main entry*/
ZTEST_SUITE(desc_sections, NULL, NULL, NULL, NULL, NULL);
