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

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

#include <sys/byteorder.h>
#include <usb/usb_device.h>
#include <usb/usb_common.h>

#include <usb/bos.h>

/* Helpers */
static void hexdump(const u8_t *data, size_t len)
{
	int n = 0;

	while (len--) {
		if (n % 16 == 0) {
			printk("%08X ", n);
		}

		printk("%02X ", *data++);

		n++;
		if (n % 8 == 0) {
			if (n % 16 == 0) {
				printk("\n");
			} else {
				printk(" ");
			}
		}
	}

	if (n % 16) {
		printk("\n");
	}
}

/*
 * Compare old style USB BOS definition with section aligned
 */

static const u8_t dummy_descriptor[] = {
	0x00, 0x01, 0x02
};

static struct webusb_bos_desc {
	struct usb_bos_descriptor bos;
	struct usb_bos_platform_descriptor platform_webusb;
	struct usb_bos_capability_webusb capability_data_webusb;
	struct usb_bos_platform_descriptor platform_msos;
	struct usb_bos_capability_msos capability_data_msos;
} __packed webusb_bos_descriptor = {
	.bos = {
		.bLength = sizeof(struct usb_bos_descriptor),
		.bDescriptorType = USB_BINARY_OBJECT_STORE_DESC,
		.wTotalLength = sizeof(struct webusb_bos_desc),
		.bNumDeviceCaps = 2,
	},
	/* WebUSB Platform Capability Descriptor:
	 * https://wicg.github.io/webusb/#webusb-platform-capability-descriptor
	 */
	.platform_webusb = {
		.bLength = sizeof(struct usb_bos_platform_descriptor)
			+ sizeof(struct usb_bos_capability_webusb),
		.bDescriptorType = USB_DEVICE_CAPABILITY_DESC,
		.bDevCapabilityType = USB_BOS_CAPABILITY_PLATFORM,
		.bReserved = 0,
		/* WebUSB Platform Capability UUID
		 * 3408b638-09a9-47a0-8bfd-a0768815b665
		 */
		.PlatformCapabilityUUID = {
			0x38, 0xB6, 0x08, 0x34,
			0xA9, 0x09,
			0xA0, 0x47,
			0x8B, 0xFD,
			0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65,
		},
	},
	.capability_data_webusb = {
		.bcdVersion = sys_cpu_to_le16(0x0100),
		.bVendorCode = 0x01,
		.iLandingPage = 0x01
	},
	/* Microsoft OS 2.0 Platform Capability Descriptor
	 * See https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/
	 * microsoft-defined-usb-descriptors
	 * Adapted from the source:
	 * https://github.com/sowbug/weblight/blob/master/firmware/webusb.c
	 * (BSD-2) Thanks http://janaxelson.com/files/ms_os_20_descriptors.c
	 */
	.platform_msos = {
		.bLength = sizeof(struct usb_bos_platform_descriptor)
			+ sizeof(struct usb_bos_capability_msos),
		.bDescriptorType = USB_DEVICE_CAPABILITY_DESC,
		.bDevCapabilityType = USB_BOS_CAPABILITY_PLATFORM,
		.bReserved = 0,
		.PlatformCapabilityUUID = {
			/**
			 * MS OS 2.0 Platform Capability ID
			 * D8DD60DF-4589-4CC7-9CD2-659D9E648A9F
			 */
			0xDF, 0x60, 0xDD, 0xD8,
			0x89, 0x45,
			0xC7, 0x4C,
			0x9C, 0xD2,
			0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F,
		},
	},
	.capability_data_msos = {
		/* Windows version (8.1) (0x06030000) */
		.dwWindowsVersion = sys_cpu_to_le32(0x06030000),
		.wMSOSDescriptorSetTotalLength =
			sys_cpu_to_le16(sizeof(dummy_descriptor)),
		.bMS_VendorCode = 0x02,
		.bAltEnumCode = 0x00
	}
};

/* In a case linker places data in a different order */
static struct webusb_bos_desc_2 {
	struct usb_bos_descriptor bos;
	struct usb_bos_platform_descriptor platform_msos;
	struct usb_bos_capability_msos capability_data_msos;
	struct usb_bos_platform_descriptor platform_webusb;
	struct usb_bos_capability_webusb capability_data_webusb;
} __packed webusb_bos_descriptor_2;

USB_DEVICE_BOS_DESC_DEFINE_CAP struct usb_bos_webusb {
	struct usb_bos_platform_descriptor platform;
	struct usb_bos_capability_webusb cap;
} __packed cap_webusb = {
	.platform = {
		.bLength = sizeof(struct usb_bos_platform_descriptor) +
			sizeof(struct usb_bos_capability_webusb),
		.bDescriptorType = USB_DEVICE_CAPABILITY_DESC,
		.bDevCapabilityType = USB_BOS_CAPABILITY_PLATFORM,
		.bReserved = 0,
		/* WebUSB Platform Capability UUID
		 * 3408b638-09a9-47a0-8bfd-a0768815b665
		 */
		.PlatformCapabilityUUID = {
			0x38, 0xB6, 0x08, 0x34,
			0xA9, 0x09,
			0xA0, 0x47,
			0x8B, 0xFD,
			0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65,
		},
	},
	.cap = {
		.bcdVersion = sys_cpu_to_le16(0x0100),
		.bVendorCode = 0x01,
		.iLandingPage = 0x01
	},
};

USB_DEVICE_BOS_DESC_DEFINE_CAP struct usb_bos_msosv2 {
	struct usb_bos_platform_descriptor platform;
	struct usb_bos_capability_msos cap;
} __packed cap_msosv2 = {
	.platform = {
		.bLength = sizeof(struct usb_bos_platform_descriptor)
			+ sizeof(struct usb_bos_capability_msos),
		.bDescriptorType = USB_DEVICE_CAPABILITY_DESC,
		.bDevCapabilityType = USB_BOS_CAPABILITY_PLATFORM,
		.bReserved = 0,
		.PlatformCapabilityUUID = {
			/**
			 * MS OS 2.0 Platform Capability ID
			 * D8DD60DF-4589-4CC7-9CD2-659D9E648A9F
			 */
			0xDF, 0x60, 0xDD, 0xD8,
			0x89, 0x45,
			0xC7, 0x4C,
			0x9C, 0xD2,
			0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F,
		},
	},
	.cap = {
		/* Windows version (8.1) (0x06030000) */
		.dwWindowsVersion = sys_cpu_to_le32(0x06030000),
		.wMSOSDescriptorSetTotalLength =
			sys_cpu_to_le16(sizeof(dummy_descriptor)),
		.bMS_VendorCode = 0x02,
		.bAltEnumCode = 0x00,
	},
};

static void test_usb_bos_macros(void)
{
	const struct usb_bos_descriptor *hdr = usb_bos_get_header();
	size_t len = usb_bos_get_length();

	TC_PRINT("length %zu\n", len);

	usb_bos_register_cap((void *)&cap_webusb);
	usb_bos_register_cap((void *)&cap_msosv2);

	/* usb_bos_fix_total_length(); corrected with register */

	hexdump((void *)hdr, len);
	hexdump((void *)&webusb_bos_descriptor, sizeof(cap_webusb));
	hexdump((void *)&webusb_bos_descriptor_2, sizeof(cap_msosv2));

	zassert_true(len ==
		     sizeof(struct usb_bos_descriptor) +
		     sizeof(cap_webusb) +
		     sizeof(cap_msosv2),
		     "Incorrect calculated length");
	zassert_true(!memcmp(hdr, &webusb_bos_descriptor, len) ||
		     !memcmp(hdr, &webusb_bos_descriptor_2, len),
		     "Wrong data");
}

static void test_usb_bos(void)
{
	struct usb_setup_packet setup;
	s32_t len = 0;
	u8_t *data = NULL;
	int ret;

	/* Already registered due to previous test */

	setup.wValue = (DESCRIPTOR_TYPE_BOS & 0xFF) << 8;

	ret = usb_handle_bos(&setup, &len, &data);

	TC_PRINT("%s: ret %d len %u data %p\n", __func__, ret, len, data);

	zassert_true(!ret, "Return code failed");
	zassert_equal(len, sizeof(webusb_bos_descriptor), "Wrong length");
	zassert_true(!memcmp(data, &webusb_bos_descriptor, len) ||
		     !memcmp(data, &webusb_bos_descriptor_2, len),
		     "Wrong data");
}

/*test case main entry*/
void test_main(void)
{
	/* Prepare webusb_bos_descriptor_2 */
	memcpy(&webusb_bos_descriptor_2.bos,
	       &webusb_bos_descriptor.bos,
	       sizeof(struct usb_bos_descriptor));

	memcpy(&webusb_bos_descriptor_2.platform_msos,
	       &webusb_bos_descriptor.platform_msos,
	       sizeof(struct usb_bos_platform_descriptor));
	memcpy(&webusb_bos_descriptor_2.capability_data_msos,
	       &webusb_bos_descriptor.capability_data_msos,
	       sizeof(struct usb_bos_capability_msos));

	memcpy(&webusb_bos_descriptor_2.platform_webusb,
	       &webusb_bos_descriptor.platform_webusb,
	       sizeof(struct usb_bos_platform_descriptor));
	memcpy(&webusb_bos_descriptor_2.capability_data_webusb,
	       &webusb_bos_descriptor.capability_data_webusb,
	       sizeof(struct usb_bos_capability_webusb));

	ztest_test_suite(test_osdesc,
			 ztest_unit_test(test_usb_bos_macros),
			 ztest_unit_test(test_usb_bos));
	ztest_run_test_suite(test_osdesc);
}
