/*
 * Copyright (c) 2017 PHYTEC Messtechnik GmbH
 * Copyright (c) 2017, 2018 Intel Corporation
 * Copyright (c) 2022 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/usb/usbd.h>
#include <zephyr/drivers/hwinfo.h>

#include "usbd_desc.h"
#include "usbd_device.h"

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(usbd_desc, CONFIG_USBD_LOG_LEVEL);

/*
 * The last index of the initializer_string without null character is:
 *   ascii_idx_max = bLength / 2 - 2
 * Use this macro to determine the last index of ASCII7 string.
 */
#define USB_BSTRING_ASCII_IDX_MAX(n)	(n / 2 - 2)

/*
 * The last index of the bString is:
 *   utf16le_idx_max = sizeof(initializer_string) * 2 - 2 - 1
 *   utf16le_idx_max = bLength - 2 - 1
 * Use this macro to determine the last index of UTF16LE string.
 */
#define USB_BSTRING_UTF16LE_IDX_MAX(n)	(n - 3)

/**
 * @brief Transform ASCII-7 string descriptor to UTF16-LE
 *
 * This function transforms ASCII-7 string descriptor
 * into a UTF16-LE.
 *
 * @param[in] dn     Pointer to descriptor node
 */
static void usbd_ascii7_to_utf16le(struct usbd_desc_node *const dn)
{
	struct usb_string_descriptor *desc = dn->desc;
	int idx_max = USB_BSTRING_UTF16LE_IDX_MAX(desc->bLength);
	int ascii_idx_max = USB_BSTRING_ASCII_IDX_MAX(desc->bLength);
	uint8_t *buf = (uint8_t *)&desc->bString;

	LOG_DBG("idx_max %d, ascii_idx_max %d, buf %p",
		idx_max, ascii_idx_max, buf);

	for (int i = idx_max; i >= 0; i -= 2) {
		LOG_DBG("char %c : %x, idx %d -> %d",
			buf[ascii_idx_max],
			buf[ascii_idx_max],
			ascii_idx_max, i);
		__ASSERT(buf[ascii_idx_max] > 0x1F && buf[ascii_idx_max] < 0x7F,
			 "Only printable ascii-7 characters are allowed in USB "
			 "string descriptors");
		buf[i] = 0U;
		buf[i - 1] = buf[ascii_idx_max--];
	}
}

/**
 * @brief Get common USB descriptor
 *
 * Get descriptor from internal descrptor list.
 *
 * @param[in] dn     Pointer to descriptor node
 *
 * @return 0 on success, other values on fail.
 */
static int usbd_get_sn_from_hwid(struct usbd_desc_node *const dn)
{
	static const char hex[] = "0123456789ABCDEF";
	struct usb_string_descriptor *desc = dn->desc;
	uint8_t *desc_data = (uint8_t *)&desc->bString;
	uint8_t hwid[16];
	ssize_t hwid_len;
	ssize_t min_len;

	hwid_len = hwinfo_get_device_id(hwid, sizeof(hwid));
	if (hwid_len < 0) {
		if (hwid_len == -ENOSYS) {
			LOG_WRN("hwinfo not implemented");
			return 0;
		}

		return hwid_len;
	}

	min_len = MIN(hwid_len, desc->bLength / 2);
	for (size_t i = 0; i < min_len; i++) {
		desc_data[i * 2] = hex[hwid[i] >> 4];
		desc_data[i * 2 + 1] = hex[hwid[i] & 0xF];
	}

	LOG_HEXDUMP_DBG(&desc->bString, desc->bLength, "SerialNumber");

	return 0;
}

void *usbd_get_descriptor(struct usbd_contex *const uds_ctx,
			  const uint8_t type, const uint8_t idx)
{
	struct usbd_desc_node *tmp;
	struct usb_desc_header *dh;

	SYS_SLIST_FOR_EACH_CONTAINER(&uds_ctx->descriptors, tmp, node) {
		dh = tmp->desc;
		if (tmp->idx == idx && dh->bDescriptorType == type) {
			return tmp->desc;
		}
	}

	return NULL;
}

int usbd_desc_remove_all(struct usbd_contex *const uds_ctx)
{
	struct usbd_desc_node *tmp;
	sys_snode_t *node;

	while ((node = sys_slist_get(&uds_ctx->descriptors))) {
		tmp = CONTAINER_OF(node, struct usbd_desc_node, node);
		LOG_DBG("Remove descriptor node %p", tmp);
	}

	return 0;
}

int usbd_add_descriptor(struct usbd_contex *const uds_ctx,
			struct usbd_desc_node *const desc_nd)
{
	struct usb_desc_header *head;
	uint8_t type;
	int ret = 0;

	usbd_device_lock(uds_ctx);

	head = desc_nd->desc;
	type = head->bDescriptorType;
	if (usbd_get_descriptor(uds_ctx, type, desc_nd->idx)) {
		ret = -EALREADY;
		goto add_descriptor_error;
	}

	if (type == USB_DESC_STRING) {
		struct usb_device_descriptor *dev_desc = uds_ctx->desc;

		if (dev_desc == NULL) {
			ret = -EPERM;
			goto add_descriptor_error;
		}

		switch (desc_nd->idx) {
		case USBD_DESC_MANUFACTURER_IDX:
			dev_desc->iManufacturer = desc_nd->idx;
			break;
		case USBD_DESC_PRODUCT_IDX:
			dev_desc->iProduct = desc_nd->idx;
			break;
		case USBD_DESC_SERIAL_NUMBER_IDX:
			/* FIXME, should we force the use of hwid here? */
			ret = usbd_get_sn_from_hwid(desc_nd);
			dev_desc->iSerialNumber = desc_nd->idx;
			break;
		default:
			break;
		}

		if (desc_nd->idx) {
			/* FIXME, should we force ascii7 -> utf16le? */
			usbd_ascii7_to_utf16le(desc_nd);
		}
	}

	sys_slist_append(&uds_ctx->descriptors, &desc_nd->node);

add_descriptor_error:
	usbd_device_unlock(uds_ctx);
	return ret;
}
