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

#define SYS_LOG_LEVEL 3
#define SYS_LOG_DOMAIN "wpanusb"
#include <logging/sys_log.h>

#include <linker/sections.h>
#include <toolchain.h>
#include <string.h>
#include <misc/printk.h>

#include <device.h>
#include <uart.h>

#include <misc/util.h>
#include <shell/shell.h>

#include <net/buf.h>

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

#include <net/ieee802154_radio.h>
#include <net_private.h>

#include "wpanusb.h"

#define WPANUSB_SUBCLASS	0
#define WPANUSB_PROTOCOL	0

#define WPANUSB_BUFFER_SIZE	64

/* Max packet size for endpoints */
#define WPANUSB_BULK_EP_MPS		64

/* Max packet size for Interrupt endpoints */
#define WPANUSB_INTERRUPT_EP_MPS	16

/* Max Bluetooth command data size */
#define WPANUSB_CLASS_MAX_DATA_SIZE	100

#define VENDOR_ID			0x8086 /* Intel Hardware */
#define PRODUCT_ID			0xFF03 /* TODO: Find  better id */
#define DEVICE_RELNUM			0x0100

#define WPANUSB_NUM_CONF		1

#define WPANUSB_NUM_ITF			1

#define WPANUSB_IF1_NUM_EP		1
/* Include all endpoints, also alternate configurations */
#define WPANUSB_NUM_EP		(WPANUSB_IF1_NUM_EP)

#define WPANUSB_ENDP_BULK_IN		0x81

#define WPANUSB_CONF_SIZE (USB_CONFIGURATION_DESC_SIZE + \
			 (WPANUSB_NUM_ITF * USB_INTERFACE_DESC_SIZE) + \
			 (WPANUSB_NUM_EP * USB_ENDPOINT_DESC_SIZE))

/* Misc. macros */
#define LOW_BYTE(x)	((x) & 0xFF)
#define HIGH_BYTE(x)	((x) >> 8)

static struct device *wpanusb_dev;

static struct ieee802154_radio_api *radio_api;
static struct device *ieee802154_dev;

static struct k_fifo tx_queue;

/**
 * Stack for the tx thread.
 */
static K_THREAD_STACK_DEFINE(tx_stack, 1024);
static struct k_thread tx_thread_data;

#define DEV_DATA(dev) \
	((struct wpanusb_dev_data_t * const)(dev)->driver_data)

/* Device data structure */
struct wpanusb_dev_data_t {
	/* USB device status code */
	enum usb_dc_status_code usb_status;
	u8_t interface_data[WPANUSB_CLASS_MAX_DATA_SIZE];
	u8_t notification_sent;
};

/**
 * ieee802.15.4 USB descriptors configuration
 */
static const u8_t wpanusb_desc[] = {
	/* Device descriptor */
	USB_DEVICE_DESC_SIZE,		/* Descriptor size */
	USB_DEVICE_DESC,		/* Descriptor type */
	LOW_BYTE(USB_1_1),
	HIGH_BYTE(USB_1_1),		/* USB version in BCD format */
	CUSTOM_CLASS,			/* Class */
	WPANUSB_SUBCLASS,		/* SubClass - Interface specific */
	WPANUSB_PROTOCOL,		/* Protocol - Interface specific */
	MAX_PACKET_SIZE0,		/* Max Packet Size */
	LOW_BYTE(VENDOR_ID),
	HIGH_BYTE(VENDOR_ID),		/* Vendor Id */
	LOW_BYTE(PRODUCT_ID),
	HIGH_BYTE(PRODUCT_ID),		/* Product Id */
	LOW_BYTE(DEVICE_RELNUM),
	HIGH_BYTE(DEVICE_RELNUM),	/* Device Release Number */
	/* Index of Manufacturer String Descriptor */
	0x00,
	/* Index of Product String Descriptor */
	0x00,
	/* Index of Serial Number String Descriptor */
	0x00,
	WPANUSB_NUM_CONF,		/* Number of Possible Configuration */

	/* Configuration descriptor */
	USB_CONFIGURATION_DESC_SIZE,	/* Descriptor size */
	USB_CONFIGURATION_DESC,		/* Descriptor type */
	/* Total length in bytes of data returned */
	LOW_BYTE(WPANUSB_CONF_SIZE),
	HIGH_BYTE(WPANUSB_CONF_SIZE),
	WPANUSB_NUM_ITF,		/* Number of interfaces */
	0x01,				/* Configuration value */
	0x00,				/* Index of the Configuration string */
	USB_CONFIGURATION_ATTRIBUTES,	/* Attributes */
	MAX_LOW_POWER,			/* Max power consumption */

	/* Interface descriptor 0 */
	USB_INTERFACE_DESC_SIZE,	/* Descriptor size */
	USB_INTERFACE_DESC,		/* Descriptor type */
	0x00,				/* Interface index */
	0x00,				/* Alternate setting */
	WPANUSB_IF1_NUM_EP,		/* Number of Endpoints */
	CUSTOM_CLASS,			/* Class */
	WPANUSB_SUBCLASS,		/* SubClass */
	WPANUSB_PROTOCOL,		/* Protocol */
	/* Index of the Interface String Descriptor */
	0x00,

	/* Endpoint IN */
	USB_ENDPOINT_DESC_SIZE,		/* Descriptor size */
	USB_ENDPOINT_DESC,		/* Descriptor type */
	WPANUSB_ENDP_BULK_IN,		/* Endpoint address */
	USB_DC_EP_BULK,			/* Attributes */
	LOW_BYTE(WPANUSB_BULK_EP_MPS),
	HIGH_BYTE(WPANUSB_BULK_EP_MPS),	/* Max packet size */
	0x00,				/* Interval */

#if 0
	/* String descriptor language, only one, so min size 4 bytes.
	 * 0x0409 English(US) language code used
	 */
	USB_STRING_DESC_SIZE,           /* Descriptor size */
	USB_STRING_DESC,                /* Descriptor type */
	0x09,
	0x04,

	/* Manufacturer String Descriptor "Intel" */
	0x0C,
	USB_STRING_DESC,
	'I', 0, 'n', 0, 't', 0, 'e', 0, 'l', 0,

	/* Product String Descriptor */
	0x10,
	USB_STRING_DESC,
	'Q', 0, 'U', 0, 'A', 0, 'R', 0, 'Q', 0, 'A', 0, 'T', 0,

	/* Serial Number String Descriptor "00.01" */
	0x0C,
	USB_STRING_DESC,
	'0', 0, '0', 0, '.', 0, '0', 0, '1', 0,
#endif
};

#ifdef VERBOSE_DEBUG
/* TODO: move to standard utils */
static void hexdump(const char *str, const u8_t *packet, size_t length)
{
	int n = 0;

	if (!length) {
		printk("%s zero-length signal packet\n", str);
		return;
	}

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

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

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

	if (n % 16) {
		printk("\n");
	}
}
#else
#define hexdump(...)
#endif

/* EP Bulk IN handler, used to send data to the Host */
static void wpanusb_bulk_in(u8_t ep, enum usb_dc_ep_cb_status_code ep_status)
{
}

/* Describe EndPoints configuration */
static struct usb_ep_cfg_data wpanusb_ep[] = {
	{
		.ep_cb = wpanusb_bulk_in,
		.ep_addr = WPANUSB_ENDP_BULK_IN
	},
};

static void wpanusb_status_cb(enum usb_dc_status_code status, u8_t *param)
{
	struct wpanusb_dev_data_t * const dev_data = DEV_DATA(wpanusb_dev);

	ARG_UNUSED(param);

	/* Store the new status */
	dev_data->usb_status = status;

	/* Check the USB status and do needed action if required */
	switch (status) {
	case USB_DC_ERROR:
		SYS_LOG_DBG("USB device error");
		break;
	case USB_DC_RESET:
		SYS_LOG_DBG("USB device reset detected");
		break;
	case USB_DC_CONNECTED:
		SYS_LOG_DBG("USB device connected");
		break;
	case USB_DC_CONFIGURED:
		SYS_LOG_DBG("USB device configured");
		break;
	case USB_DC_DISCONNECTED:
		SYS_LOG_DBG("USB device disconnected");
		break;
	case USB_DC_SUSPEND:
		SYS_LOG_DBG("USB device suspended");
		break;
	case USB_DC_RESUME:
		SYS_LOG_DBG("USB device resumed");
		break;
	case USB_DC_UNKNOWN:
	default:
		SYS_LOG_DBG("USB unknown state");
		break;
		}
}

static int wpanusb_class_handler(struct usb_setup_packet *setup,
				 s32_t *len, u8_t **data)
{
	SYS_LOG_DBG("len %d", *len);

	hexdump(">", *data, *len);

	return 0;
}

static int wpanusb_custom_handler(struct usb_setup_packet *setup,
				  s32_t *len, u8_t **data)
{
	/**
	 * FIXME:
	 * Keep custom handler for now in a case some data is sent
	 * over this endpoint, at the moment return to higher layer.
	 */
	return -ENOTSUP;
}

static int try_write(u8_t ep, u8_t *data, u16_t len)
{
	while (1) {
		int ret = usb_write(ep, data, len, NULL);

		switch (ret) {
		case -EAGAIN:
			break;
		/* TODO: Handle other error codes */
		default:
			return ret;
		}
	}
}

/* Decode wpanusb commands */

static int set_channel(void *data, int len)
{
	struct set_channel *req = data;

	SYS_LOG_DBG("page %u channel %u", req->page, req->channel);

	return radio_api->set_channel(ieee802154_dev, req->channel);
}

static int set_ieee_addr(void *data, int len)
{
	struct set_ieee_addr *req = data;

	SYS_LOG_DBG("len %u", len);

	if (IEEE802154_HW_FILTER &
	    radio_api->get_capabilities(ieee802154_dev)) {
		struct ieee802154_filter filter;

		filter.ieee_addr = (u8_t *)&req->ieee_addr;

		return radio_api->set_filter(ieee802154_dev,
					     IEEE802154_FILTER_TYPE_IEEE_ADDR,
					     &filter);
	}

	return 0;
}

static int set_short_addr(void *data, int len)
{
	struct set_short_addr *req = data;

	SYS_LOG_DBG("len %u", len);


	if (IEEE802154_HW_FILTER &
	    radio_api->get_capabilities(ieee802154_dev)) {
		struct ieee802154_filter filter;

		filter.short_addr = req->short_addr;

		return radio_api->set_filter(ieee802154_dev,
					     IEEE802154_FILTER_TYPE_SHORT_ADDR,
					     &filter);
	}

	return 0;
}

static int set_pan_id(void *data, int len)
{
	struct set_pan_id *req = data;

	SYS_LOG_DBG("len %u", len);

	if (IEEE802154_HW_FILTER &
	    radio_api->get_capabilities(ieee802154_dev)) {
		struct ieee802154_filter filter;

		filter.pan_id = req->pan_id;

		return radio_api->set_filter(ieee802154_dev,
					     IEEE802154_FILTER_TYPE_PAN_ID,
					     &filter);
	}

	return 0;
}

static int start(void)
{
	SYS_LOG_INF("Start IEEE 802.15.4 device");

	return radio_api->start(ieee802154_dev);
}

static int stop(void)
{
	SYS_LOG_INF("Stop IEEE 802.15.4 device");

	return radio_api->stop(ieee802154_dev);
}

static int tx(struct net_pkt *pkt)
{
	struct net_buf *buf = net_buf_frag_last(pkt->frags);
	u8_t seq = net_buf_pull_u8(buf);
	int retries = 3;
	int ret;

	SYS_LOG_DBG("len %d seq %u", buf->len, seq);

	do {
		ret = radio_api->tx(ieee802154_dev, pkt, buf);
	} while (ret && retries--);

	if (ret) {
		SYS_LOG_ERR("Error sending data, seq %u", seq);
		/* Send seq = 0 for unsuccessful send */
		seq = 0;
	}

	try_write(WPANUSB_ENDP_BULK_IN, &seq, sizeof(seq));

	return ret;
}

/**
 * Vendor handler is executed in the ISR context, queue data for
 * later processing
 */
static int wpanusb_vendor_handler(struct usb_setup_packet *setup,
				  s32_t *len, u8_t **data)
{
	struct net_pkt *pkt;
	struct net_buf *buf;

	pkt = net_pkt_get_reserve_tx(0, K_NO_WAIT);
	if (!pkt) {
		return -ENOMEM;
	}

	buf = net_pkt_get_frag(pkt, K_NO_WAIT);
	if (!buf) {
		net_pkt_unref(pkt);
		return -ENOMEM;
	}

	net_pkt_frag_insert(pkt, buf);

	net_buf_add_u8(buf, setup->bRequest);

	/* Add seq to TX */
	if (setup->bRequest == TX) {
		net_buf_add_u8(buf, setup->wIndex);
	}

	memcpy(net_buf_add(buf, *len), *data, *len);

	SYS_LOG_DBG("len %u seq %u", *len, setup->wIndex);

	k_fifo_put(&tx_queue, pkt);

	return 0;
}

static void tx_thread(void)
{
	SYS_LOG_DBG("Tx thread started");

	while (1) {
		u8_t cmd;
		struct net_pkt *pkt;
		struct net_buf *buf;

		pkt = k_fifo_get(&tx_queue, K_FOREVER);
		buf = net_buf_frag_last(pkt->frags);
		cmd = net_buf_pull_u8(buf);

		hexdump(">", buf->data, buf->len);

		switch (cmd) {
		case RESET:
			SYS_LOG_DBG("Reset device");
			break;
		case TX:
			tx(pkt);
			break;
		case START:
			start();
			break;
		case STOP:
			stop();
			break;
		case SET_CHANNEL:
			set_channel(buf->data, buf->len);
			break;
		case SET_IEEE_ADDR:
			set_ieee_addr(buf->data, buf->len);
			break;
		case SET_SHORT_ADDR:
			set_short_addr(buf->data, buf->len);
			break;
		case SET_PAN_ID:
			set_pan_id(buf->data, buf->len);
			break;
		default:
			SYS_LOG_ERR("%x: Not handled for now", cmd);
			break;
		}

		net_pkt_unref(pkt);

		k_yield();
	}
}

/* TODO: FIXME: correct buffer size */
static u8_t buffer[300];

static struct usb_cfg_data wpanusb_config = {
	.usb_device_description = wpanusb_desc,
	.cb_usb_status = wpanusb_status_cb,
	.interface = {
		.class_handler = wpanusb_class_handler,
		.custom_handler = wpanusb_custom_handler,
		.vendor_handler = wpanusb_vendor_handler,
		.vendor_data = buffer,
	},
	.num_endpoints = ARRAY_SIZE(wpanusb_ep),
	.endpoint = wpanusb_ep,
};

static int wpanusb_init(struct device *dev)
{
	struct wpanusb_dev_data_t * const dev_data = DEV_DATA(dev);
	int ret;

	SYS_LOG_DBG("");

	wpanusb_config.interface.payload_data = dev_data->interface_data;
	wpanusb_dev = dev;

	/* Initialize the USB driver with the right configuration */
	ret = usb_set_config(&wpanusb_config);
	if (ret < 0) {
		SYS_LOG_ERR("Failed to configure USB");
		return ret;
	}

	/* Enable USB driver */
	ret = usb_enable(&wpanusb_config);
	if (ret < 0) {
		SYS_LOG_ERR("Failed to enable USB");
		return ret;
	}

	return 0;
}

static struct wpanusb_dev_data_t wpanusb_dev_data = {
	.usb_status = USB_DC_UNKNOWN,
};

#if BOOT_INITIALIZED
DEVICE_INIT(wpanusb, "wpanusb", &wpanusb_init,
	    &wpanusb_dev_data, NULL,
	    APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
#define wpanusb_start(dev)
#else
static struct device __dev = {
	.driver_data = &wpanusb_dev_data,
};
static void wpanusb_start(struct device *dev)
{
	wpanusb_init(dev);
}
#endif

static void init_tx_queue(void)
{
	/* Transmit queue init */
	k_fifo_init(&tx_queue);

	k_thread_create(&tx_thread_data, tx_stack,
			K_THREAD_STACK_SIZEOF(tx_stack),
			(k_thread_entry_t)tx_thread,
			NULL, NULL, NULL, K_PRIO_COOP(8), 0, K_NO_WAIT);
}

extern enum net_verdict ieee802154_radio_handle_ack(struct net_if *iface,
						    struct net_pkt *pkt)
{
	/* parse on higher layer */
	return NET_CONTINUE;
}

int ieee802154_radio_send(struct net_if *iface, struct net_pkt *pkt)
{
	SYS_LOG_DBG("");

	return -ENOTSUP;
}

void ieee802154_init(struct net_if *iface)
{
	SYS_LOG_DBG("");
}

int net_recv_data(struct net_if *iface, struct net_pkt *pkt)
{
	struct net_buf *frag;

	SYS_LOG_DBG("Got data, pkt %p, frags->len %d",
		    pkt, net_pkt_get_len(pkt));

	frag = net_buf_frag_last(pkt->frags);

	/**
	 * Add length 1 byte, do not forget to reserve it
	 */
	net_buf_push_u8(frag, net_pkt_get_len(pkt) - 1);

	hexdump("<", frag->data, net_pkt_get_len(pkt));

	try_write(WPANUSB_ENDP_BULK_IN, frag->data, net_pkt_get_len(pkt));

	net_pkt_unref(pkt);

	return 0;
}

static int shell_cmd_help(int argc, char *argv[])
{
	/* Keep the commands in alphabetical order */
	printk("wpanusb help\n");

	return 0;
}

struct shell_cmd commands[] = {
	{ "help", shell_cmd_help, "help" },
	{ NULL, NULL }
};

void main(void)
{
	wpanusb_start(&__dev);

	SYS_LOG_INF("Start");

#if DYNAMIC_REGISTER
	ieee802154_dev = ieee802154_register_raw();
#else
	ieee802154_dev = device_get_binding(CONFIG_IEEE802154_CC2520_DRV_NAME);
	if (!ieee802154_dev) {
		SYS_LOG_ERR("Cannot get CC250 device");
		return;
	}
#endif

	/* Initialize net_pkt */
	net_pkt_init();

	/* Initialize transmit queue */
	init_tx_queue();

	radio_api = (struct ieee802154_radio_api *)ieee802154_dev->driver_api;

	/* TODO: Initialize more */

	SYS_LOG_DBG("radio_api %p initialized", radio_api);

	SHELL_REGISTER("wpan", commands);
}
