/*
 * Copyright (c) 2022 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/drivers/usb/udc.h>
#include <zephyr/usb/usbd.h>

#include "usbd_device.h"
#include "usbd_config.h"
#include "usbd_class.h"
#include "usbd_ch9.h"
#include "usbd_desc.h"

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

/*
 * All the functions below are part of public USB device support API.
 */

enum usbd_speed usbd_bus_speed(const struct usbd_contex *const uds_ctx)
{
	return uds_ctx->status.speed;
}

enum usbd_speed usbd_caps_speed(const struct usbd_contex *const uds_ctx)
{
	struct udc_device_caps caps = udc_caps(uds_ctx->dev);

	/* For now, either high speed is supported or not. */
	if (caps.hs) {
		return USBD_SPEED_HS;
	}

	return USBD_SPEED_FS;
}

static struct usb_device_descriptor *
get_device_descriptor(struct usbd_contex *const uds_ctx,
		      const enum usbd_speed speed)
{
	switch (speed) {
	case USBD_SPEED_FS:
		return uds_ctx->fs_desc;
	case USBD_SPEED_HS:
		return uds_ctx->hs_desc;
	default:
		__ASSERT(false, "Not supported speed");
		return NULL;
	}
}

int usbd_device_set_bcd(struct usbd_contex *const uds_ctx,
			const enum usbd_speed speed, const uint16_t bcd)
{
	struct usb_device_descriptor *desc;
	int ret = 0;

	usbd_device_lock(uds_ctx);

	if (usbd_is_enabled(uds_ctx)) {
		ret = -EALREADY;
		goto set_bcd_exit;
	}

	desc = get_device_descriptor(uds_ctx, speed);
	desc->bcdUSB = sys_cpu_to_le16(bcd);

set_bcd_exit:
	usbd_device_unlock(uds_ctx);
	return ret;
}

int usbd_device_set_vid(struct usbd_contex *const uds_ctx,
			 const uint16_t vid)
{
	struct usb_device_descriptor *fs_desc, *hs_desc;
	int ret = 0;

	usbd_device_lock(uds_ctx);

	if (usbd_is_enabled(uds_ctx)) {
		ret = -EALREADY;
		goto set_vid_exit;
	}

	fs_desc = get_device_descriptor(uds_ctx, USBD_SPEED_FS);
	fs_desc->idVendor = sys_cpu_to_le16(vid);

	hs_desc = get_device_descriptor(uds_ctx, USBD_SPEED_HS);
	hs_desc->idVendor = sys_cpu_to_le16(vid);

set_vid_exit:
	usbd_device_unlock(uds_ctx);
	return ret;
}

int usbd_device_set_pid(struct usbd_contex *const uds_ctx,
			 const uint16_t pid)
{
	struct usb_device_descriptor *fs_desc, *hs_desc;
	int ret = 0;

	usbd_device_lock(uds_ctx);

	if (usbd_is_enabled(uds_ctx)) {
		ret = -EALREADY;
		goto set_pid_exit;
	}

	fs_desc = get_device_descriptor(uds_ctx, USBD_SPEED_FS);
	fs_desc->idProduct = sys_cpu_to_le16(pid);

	hs_desc = get_device_descriptor(uds_ctx, USBD_SPEED_HS);
	hs_desc->idProduct = sys_cpu_to_le16(pid);

set_pid_exit:
	usbd_device_unlock(uds_ctx);
	return ret;
}

int usbd_device_set_code_triple(struct usbd_contex *const uds_ctx,
				const enum usbd_speed speed,
				const uint8_t base_class,
				const uint8_t subclass, const uint8_t protocol)
{
	struct usb_device_descriptor *desc;
	int ret = 0;

	usbd_device_lock(uds_ctx);

	if (usbd_is_enabled(uds_ctx)) {
		ret = -EALREADY;
		goto set_code_triple_exit;
	}

	desc = get_device_descriptor(uds_ctx, speed);
	desc->bDeviceClass = base_class;
	desc->bDeviceSubClass = subclass;
	desc->bDeviceProtocol = protocol;

set_code_triple_exit:
	usbd_device_unlock(uds_ctx);
	return ret;
}

int usbd_wakeup_request(struct usbd_contex *const uds_ctx)
{
	struct udc_device_caps caps = udc_caps(uds_ctx->dev);
	int ret = 0;

	usbd_device_lock(uds_ctx);

	if (!caps.rwup) {
		LOG_ERR("Remote wakeup feature not supported");
		ret = -ENOTSUP;
		goto wakeup_request_error;
	}

	if (!uds_ctx->status.rwup || !usbd_is_suspended(uds_ctx)) {
		LOG_ERR("Remote wakeup feature not enabled or not suspended");
		ret = -EACCES;
		goto wakeup_request_error;
	}

	ret = udc_host_wakeup(uds_ctx->dev);

wakeup_request_error:
	usbd_device_unlock(uds_ctx);

	return ret;
}

bool usbd_is_suspended(struct usbd_contex *uds_ctx)
{
	return uds_ctx->status.suspended;
}

int usbd_init(struct usbd_contex *const uds_ctx)
{
	int ret;

	usbd_device_lock(uds_ctx);

	if (uds_ctx->dev == NULL) {
		ret = -ENODEV;
		goto init_exit;
	}

	if (usbd_is_initialized(uds_ctx)) {
		LOG_WRN("USB device support is already initialized");
		ret = -EALREADY;
		goto init_exit;
	}

	if (!device_is_ready(uds_ctx->dev)) {
		LOG_ERR("USB device controller is not ready");
		ret = -ENODEV;
		goto init_exit;
	}

	ret = usbd_device_init_core(uds_ctx);
	if (ret) {
		goto init_exit;
	}

	memset(&uds_ctx->ch9_data, 0, sizeof(struct usbd_ch9_data));
	uds_ctx->status.initialized = true;

init_exit:
	usbd_device_unlock(uds_ctx);
	return ret;
}

int usbd_enable(struct usbd_contex *const uds_ctx)
{
	int ret;

	usbd_device_lock(uds_ctx);

	if (!usbd_is_initialized(uds_ctx)) {
		LOG_WRN("USB device support is not initialized");
		ret = -EPERM;
		goto enable_exit;
	}

	if (usbd_is_enabled(uds_ctx)) {
		LOG_WRN("USB device support is already enabled");
		ret = -EALREADY;
		goto enable_exit;
	}

	ret = udc_enable(uds_ctx->dev);
	if (ret != 0) {
		LOG_ERR("Failed to enable controller");
		goto enable_exit;
	}

	ret = usbd_init_control_pipe(uds_ctx);
	if (ret != 0) {
		udc_disable(uds_ctx->dev);
		goto enable_exit;
	}

	uds_ctx->status.enabled = true;

enable_exit:
	usbd_device_unlock(uds_ctx);
	return ret;
}

int usbd_disable(struct usbd_contex *const uds_ctx)
{
	int ret;

	if (!usbd_is_enabled(uds_ctx)) {
		LOG_WRN("USB device support is already disabled");
		return -EALREADY;
	}

	usbd_device_lock(uds_ctx);

	ret = usbd_config_set(uds_ctx, 0);
	if (ret) {
		LOG_ERR("Failed to reset configuration");
	}

	ret = udc_disable(uds_ctx->dev);
	if (ret) {
		LOG_ERR("Failed to disable USB device");
	}

	uds_ctx->status.enabled = false;

	usbd_device_unlock(uds_ctx);

	return ret;
}

int usbd_shutdown(struct usbd_contex *const uds_ctx)
{
	int ret;

	usbd_device_lock(uds_ctx);

	/* TODO: control request dequeue ? */
	ret = usbd_device_shutdown_core(uds_ctx);
	if (ret) {
		LOG_ERR("Failed to shutdown USB device");
	}

	uds_ctx->status.initialized = false;
	usbd_device_unlock(uds_ctx);

	return 0;
}
