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

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

#include <misc/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 %u\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, len);
	hexdump((void *)&webusb_bos_descriptor_2, len);

	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);
}
