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

/**
 * @file
 * @brief USB native_posix device driver
 */

#include <string.h>
#include <stdio.h>
#include <misc/byteorder.h>
#include <usb/usb_dc.h>
#include <usb/usb_device.h>
#include <net/net_ip.h>

#include "usb_dc_native_posix_adapt.h"

#define LOG_LEVEL CONFIG_USB_DRIVER_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(native_posix);

/* convert from endpoint address to hardware endpoint index */
#define USBIP_EP_ADDR2IDX(ep)  ((ep) & ~USB_EP_DIR_MASK)
/* get direction from endpoint address */
#define USBIP_EP_ADDR2DIR(ep)  ((ep) & USB_EP_DIR_MASK)
/* convert from hardware endpoint index and direction to endpoint address */
#define USBIP_EP_IDX2ADDR(idx, dir)    ((idx) | ((dir) & USB_EP_DIR_MASK))

#define USBIP_IN_EP_NUM		4
#define USBIP_OUT_EP_NUM	4

#define USBIP_MAX_PACKET_SIZE	64

K_THREAD_STACK_MEMBER(thread_stack, CONFIG_ARCH_POSIX_RECOMMENDED_STACK_SIZE);
static struct k_thread thread;

static void thread_main(void *a, void *b, void *c)
{
	LOG_DBG("");

	usbip_start();
}

/*
 * USBIP private structures and logic initially copied from
 * Designware USB driver
 */

/*
 * USB endpoint private structure.
 */
struct usb_ep_ctrl_prv {
	u8_t ep_ena;
	u16_t mps;
	usb_dc_ep_callback cb;
	u32_t data_len;
	u8_t buf[64];
	u8_t buf_len;
};

/*
 * USB controller private structure.
 */
static struct usbip_ctrl_prv {
	usb_dc_status_callback status_cb;
	struct usb_ep_ctrl_prv in_ep_ctrl[USBIP_IN_EP_NUM];
	struct usb_ep_ctrl_prv out_ep_ctrl[USBIP_OUT_EP_NUM];
	u8_t attached;
} usbip_ctrl;

static u8_t usbip_ep_is_valid(u8_t ep)
{
	u8_t ep_idx = USBIP_EP_ADDR2IDX(ep);

	/* Check if ep is valid */
	if ((USBIP_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) &&
	    ep_idx < USBIP_OUT_EP_NUM) {
		return 1;
	} else if ((USBIP_EP_ADDR2DIR(ep) == USB_EP_DIR_IN) &&
	    ep_idx < USBIP_IN_EP_NUM) {
		return 1;
	}

	return 0;
}

static u8_t usbip_ep_is_enabled(u8_t ep)
{
	u8_t ep_idx = USBIP_EP_ADDR2IDX(ep);

	LOG_DBG("ep %x", ep);

	/* Check if ep enabled */
	if ((USBIP_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) &&
	    usbip_ctrl.out_ep_ctrl[ep_idx].ep_ena) {
		return 1;
	} else if ((USBIP_EP_ADDR2DIR(ep) == USB_EP_DIR_IN) &&
	    usbip_ctrl.in_ep_ctrl[ep_idx].ep_ena) {
		return 1;
	}

	return 0;
}

int usb_dc_attach(void)
{
	LOG_DBG("");

	if (usbip_ctrl.attached) {
		LOG_WRN("Already attached");
		return 0;
	}

	k_thread_create(&thread, thread_stack,
			CONFIG_ARCH_POSIX_RECOMMENDED_STACK_SIZE,
			thread_main, NULL, NULL, NULL,
			K_PRIO_COOP(2), 0, K_NO_WAIT);

	usbip_ctrl.attached = 1;

	return 0;
}

int usb_dc_detach(void)
{
	LOG_DBG("");

	if (!usbip_ctrl.attached) {
		return 0;
	}

	usbip_ctrl.attached = 0;

	return 0;
}

int usb_dc_reset(void)
{
	LOG_DBG("");

	/* Clear private data */
	memset(&usbip_ctrl, 0, sizeof(usbip_ctrl));

	return 0;
}

int usb_dc_set_address(const u8_t addr)
{
	LOG_DBG("");

	return 0;
}

int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg)
{
	u8_t ep_idx = USBIP_EP_ADDR2IDX(cfg->ep_addr);

	LOG_DBG("ep %x, mps %d, type %d", cfg->ep_addr, cfg->ep_mps,
		cfg->ep_type);

	if ((cfg->ep_type == USB_DC_EP_CONTROL) && ep_idx) {
		LOG_ERR("invalid endpoint configuration");
		return -1;
	}

	if (cfg->ep_mps > USBIP_MAX_PACKET_SIZE) {
		LOG_WRN("unsupported packet size");
		return -1;
	}

	if ((USBIP_EP_ADDR2DIR(cfg->ep_addr) == USB_EP_DIR_OUT) &&
	    (ep_idx >= USBIP_OUT_EP_NUM)) {
		LOG_WRN("OUT endpoint address out of range");
		return -1;
	}

	if ((USBIP_EP_ADDR2DIR(cfg->ep_addr) == USB_EP_DIR_IN) &&
	    (ep_idx >= USBIP_IN_EP_NUM)) {
		LOG_WRN("IN endpoint address out of range");
		return -1;
	}

	return 0;
}

int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const cfg)
{
	u16_t ep_mps = cfg->ep_mps;
	u8_t ep = cfg->ep_addr;
	u8_t ep_idx = USBIP_EP_ADDR2IDX(ep);

	LOG_DBG("ep %x, mps %d, type %d", ep, ep_mps, cfg->ep_type);

	if (!usbip_ctrl.attached && !usbip_ep_is_valid(ep)) {
		return -EINVAL;
	}

	if (USBIP_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		usbip_ctrl.out_ep_ctrl[ep_idx].mps = ep_mps;
	} else {
		usbip_ctrl.in_ep_ctrl[ep_idx].mps = ep_mps;
	}

	return 0;
}

int usb_dc_ep_set_stall(const u8_t ep)
{
	LOG_DBG("ep %x", ep);

	if (!usbip_ctrl.attached && !usbip_ep_is_valid(ep)) {
		return -EINVAL;
	}

	/* Use standard reply for now */
	usb_dc_ep_write(0x80,  NULL, 0, NULL);

	return 0;
}

int usb_dc_ep_clear_stall(const u8_t ep)
{
	u8_t ep_idx = USBIP_EP_ADDR2IDX(ep);

	LOG_DBG("ep %x", ep);

	if (!usbip_ctrl.attached && !usbip_ep_is_valid(ep)) {
		return -EINVAL;
	}

	if (!ep_idx) {
		/* Not possible to clear stall for EP0 */
		return -EINVAL;
	}

	return 0;
}

int usb_dc_ep_halt(const u8_t ep)
{
	u8_t ep_idx = USBIP_EP_ADDR2IDX(ep);

	LOG_DBG("ep %x", ep);

	if (!usbip_ctrl.attached && !usbip_ep_is_valid(ep)) {
		return -EINVAL;
	}

	if (!ep_idx) {
		/* Cannot disable EP0, just set stall */
		usb_dc_ep_set_stall(ep);
	}

	return 0;
}

int usb_dc_ep_is_stalled(const u8_t ep, u8_t *const stalled)
{
	LOG_DBG("ep %x", ep);

	if (!usbip_ctrl.attached && !usbip_ep_is_valid(ep)) {
		return -EINVAL;
	}

	if (!stalled) {
		return -EINVAL;
	}

	return 0;
}

int usb_dc_ep_enable(const u8_t ep)
{
	u8_t ep_idx = USBIP_EP_ADDR2IDX(ep);

	LOG_DBG("ep %x", ep);

	if (!usbip_ctrl.attached && !usbip_ep_is_valid(ep)) {
		return -EINVAL;
	}

	/* Enable Ep */
	if (USBIP_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		usbip_ctrl.out_ep_ctrl[ep_idx].ep_ena = 1;
	} else {
		usbip_ctrl.in_ep_ctrl[ep_idx].ep_ena = 1;
	}

	return 0;
}

int usb_dc_ep_disable(const u8_t ep)
{
	LOG_DBG("ep %x", ep);

	return 0;
}

int usb_dc_ep_flush(const u8_t ep)
{
	LOG_DBG("ep %x", ep);

	if (!usbip_ctrl.attached && !usbip_ep_is_valid(ep)) {
		return -EINVAL;
	}

	if (USBIP_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		/* RX FIFO is global and cannot be flushed per EP */
		return -EINVAL;
	}

	return 0;
}

int usb_dc_ep_write(const u8_t ep, const u8_t *const data,
		    const u32_t data_len, u32_t * const ret_bytes)
{
	LOG_DBG("ep %x len %u", ep, data_len);

	if (!usbip_ctrl.attached && !usbip_ep_is_valid(ep)) {
		return -EINVAL;
	}

	/* Check if IN ep */
	if (USBIP_EP_ADDR2DIR(ep) != USB_EP_DIR_IN) {
		return -EINVAL;
	}

	/* Check if ep enabled */
	if (!usbip_ep_is_enabled(ep)) {
		LOG_WRN("ep %x disabled", ep);
		return -EINVAL;
	}

	if (USBIP_EP_ADDR2IDX(ep) == 0) {
		usbip_send_common(ep, data_len);
		usbip_send(ep, data, data_len);
	} else {
		u8_t ep_idx = USBIP_EP_ADDR2IDX(ep);
		struct usb_ep_ctrl_prv *ctrl = &usbip_ctrl.in_ep_ctrl[ep_idx];

		memcpy(ctrl->buf, data, data_len);
		ctrl->buf_len = data_len;
	}

	if (ret_bytes) {
		*ret_bytes = data_len;
	}

	return 0;
}

int usb_dc_ep_read_wait(u8_t ep, u8_t *data, u32_t max_data_len,
			u32_t *read_bytes)
{
	u32_t bytes;

	if (!usbip_ctrl.attached && !usbip_ep_is_valid(ep)) {
		LOG_ERR("No valid endpoint");
		return -EINVAL;
	}

	/* Check if OUT ep */
	if (USBIP_EP_ADDR2DIR(ep) != USB_EP_DIR_OUT) {
		LOG_ERR("Wrong endpoint direction");
		return -EINVAL;
	}

	/* Allow to read 0 bytes */
	if (!data && max_data_len) {
		LOG_ERR("Wrong arguments");
		return -EINVAL;
	}

	/* Check if ep enabled */
	if (!usbip_ep_is_enabled(ep)) {
		LOG_ERR("Not enabled endpoint");
		return -EINVAL;
	}

	LOG_DBG("ep %x max_data_len %u", ep, max_data_len);

	bytes = usbip_recv(data, max_data_len);

	if (read_bytes) {
		*read_bytes = bytes;
	}

	return 0;
}

int usb_dc_ep_read_continue(u8_t ep)
{
	u8_t ep_idx = USBIP_EP_ADDR2IDX(ep);

	if (!usbip_ctrl.attached && !usbip_ep_is_valid(ep)) {
		LOG_ERR("No valid endpoint");
		return -EINVAL;
	}

	/* Check if OUT ep */
	if (USBIP_EP_ADDR2DIR(ep) != USB_EP_DIR_OUT) {
		LOG_ERR("Wrong endpoint direction");
		return -EINVAL;
	}

	if (!usbip_ctrl.out_ep_ctrl[ep_idx].data_len) {
		/* TODO: continue read */
		/* usbip_prep_rx(ep_idx, 0); */
	}

	return 0;
}

int usb_dc_ep_read(const u8_t ep, u8_t *const data,
		   const u32_t max_data_len, u32_t * const read_bytes)
{
	LOG_DBG("ep %x max_data_len %u", ep, max_data_len);

	if (usb_dc_ep_read_wait(ep, data, max_data_len, read_bytes) != 0) {
		return -EINVAL;
	}

	if (!data && !max_data_len) {
		/* When both buffer and max data to read are zero the above
		 * call would fetch the data len and we simply return.
		 */
		return 0;
	}

	if (usb_dc_ep_read_continue(ep) != 0) {
		return -EINVAL;
	}

	return 0;
}

int usb_dc_ep_set_callback(const u8_t ep, const usb_dc_ep_callback cb)
{
	u8_t ep_idx = USBIP_EP_ADDR2IDX(ep);

	LOG_DBG("ep %x callback %p", ep, cb);

	if (!usbip_ctrl.attached && !usbip_ep_is_valid(ep)) {
		return -EINVAL;
	}

	if (USBIP_EP_ADDR2DIR(ep) == USB_EP_DIR_IN) {
		usbip_ctrl.in_ep_ctrl[ep_idx].cb = cb;
	} else {
		usbip_ctrl.out_ep_ctrl[ep_idx].cb = cb;
	}

	return 0;
}

int usb_dc_set_status_callback(const usb_dc_status_callback cb)
{
	usbip_ctrl.status_cb = cb;

	return 0;
}

int usb_dc_ep_mps(const u8_t ep)
{
	u8_t ep_idx = USBIP_EP_ADDR2IDX(ep);

	LOG_DBG("ep %x", ep);

	if (!usbip_ep_is_valid(ep)) {
		return -EINVAL;
	}

	if (USBIP_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		return usbip_ctrl.out_ep_ctrl[ep_idx].mps;
	} else {
		return usbip_ctrl.in_ep_ctrl[ep_idx].mps;
	}
}

int handle_usb_control(struct usbip_header *hdr)
{
	u8_t ep_idx = USBIP_EP_ADDR2IDX(ntohl(hdr->common.ep));
	usb_dc_ep_callback ep_cb = usbip_ctrl.out_ep_ctrl[ep_idx].cb;

	LOG_DBG("ep %x idx %u", ntohl(hdr->common.ep), ep_idx);

	if (ep_cb) {
		LOG_DBG("Call ep_cb");
		ep_cb(ntohl(hdr->common.ep), USB_DC_EP_SETUP);
	}

	return 0;
}

static void usbip_skip_setup(void)
{
	u64_t setup;

	LOG_DBG("Skip 8 bytes");

	usbip_recv((void *)&setup, sizeof(setup));
}

int handle_usb_data(struct usbip_header *hdr)
{
	u8_t ep_idx = ntohl(hdr->common.ep);
	usb_dc_ep_callback ep_cb;
	int bytes;
	u8_t ep;

	LOG_DBG("ep_idx %u", ep_idx);

	if (ntohl(hdr->common.direction) == USBIP_DIR_OUT) {
		if (ep_idx >= USBIP_OUT_EP_NUM) {
			return -EINVAL;
		}

		ep = ep_idx | USB_EP_DIR_OUT;
		ep_cb = usbip_ctrl.out_ep_ctrl[ep_idx].cb;

		ep_cb(ep, USB_DC_EP_DATA_OUT);

		/* Send ACK reply */
		bytes = usbip_send_common(ep, 0);
	} else {
		if (ep_idx >= USBIP_IN_EP_NUM) {
			return -EINVAL;
		}

		ep = ep_idx | USB_EP_DIR_IN;
		ep_cb = usbip_ctrl.in_ep_ctrl[ep_idx].cb;

		usbip_skip_setup();

		LOG_DBG("Send %u bytes", usbip_ctrl.in_ep_ctrl[ep_idx].buf_len);

		/* Send queued data */
		usbip_send_common(ep, usbip_ctrl.in_ep_ctrl[ep_idx].buf_len);
		usbip_send(ep, usbip_ctrl.in_ep_ctrl[ep_idx].buf,
			   usbip_ctrl.in_ep_ctrl[ep_idx].buf_len);

		LOG_HEXDUMP_DBG(usbip_ctrl.in_ep_ctrl[ep_idx].buf,
				usbip_ctrl.in_ep_ctrl[ep_idx].buf_len, ">");

		/* Indicate data sent */
		ep_cb(ep, USB_DC_EP_DATA_IN);
	}

	LOG_DBG("ep %x ep_cb %p", ep, ep_cb);

	return 0;
}
