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

#include <zephyr.h>
#include <init.h>

#include <usb/usb_device.h>
#include <usb/class/usb_hid.h>

#define LOG_LEVEL LOG_LEVEL_DBG
LOG_MODULE_REGISTER(main);

#define REPORT_ID_1	0x01
#define REPORT_ID_2	0x02

static struct k_delayed_work delayed_report_send;

static struct device *hdev;

#define REPORT_TIMEOUT K_SECONDS(2)

/* Some HID sample Report Descriptor */
static const u8_t hid_report_desc[] = {
	/* 0x05, 0x01,		USAGE_PAGE (Generic Desktop)		*/
	HID_GI_USAGE_PAGE, USAGE_GEN_DESKTOP,
	/* 0x09, 0x00,		USAGE (Undefined)			*/
	HID_LI_USAGE, USAGE_GEN_DESKTOP_UNDEFINED,
	/* 0xa1, 0x01,		COLLECTION (Application)		*/
	HID_MI_COLLECTION, COLLECTION_APPLICATION,
	/* 0x15, 0x00,			LOGICAL_MINIMUM one-byte (0)	*/
	HID_GI_LOGICAL_MIN(1), 0x00,
	/* 0x26, 0xff, 0x00,		LOGICAL_MAXIMUM two-bytes (255)	*/
	HID_GI_LOGICAL_MAX(2), 0xFF, 0x00,
	/* 0x85, 0x01,			REPORT_ID (1)			*/
	HID_GI_REPORT_ID, REPORT_ID_1,
	/* 0x75, 0x08,			REPORT_SIZE (8) in bits		*/
	HID_GI_REPORT_SIZE, 0x08,
	/* 0x95, 0x01,			REPORT_COUNT (1)		*/
	HID_GI_REPORT_COUNT, 0x01,
	/* 0x09, 0x00,			USAGE (Undefined)		*/
	HID_LI_USAGE, USAGE_GEN_DESKTOP_UNDEFINED,
	/* v0x81, 0x82,			INPUT (Data,Var,Abs,Vol)	*/
	HID_MI_INPUT, 0x82,
	/* 0x85, 0x02,			REPORT_ID (2)			*/
	HID_GI_REPORT_ID, REPORT_ID_2,
	/* 0x75, 0x08,			REPORT_SIZE (8) in bits		*/
	HID_GI_REPORT_SIZE, 0x08,
	/* 0x95, 0x01,			REPORT_COUNT (1)		*/
	HID_GI_REPORT_COUNT, 0x01,
	/* 0x09, 0x00,			USAGE (Undefined)		*/
	HID_LI_USAGE, USAGE_GEN_DESKTOP_UNDEFINED,
	/* 0x91, 0x82,			OUTPUT (Data,Var,Abs,Vol)	*/
	HID_MI_OUTPUT, 0x82,
	/* 0xc0			END_COLLECTION			*/
	HID_MI_COLLECTION_END,
};

static void send_report(struct k_work *work)
{
	static u8_t report_1[2] = { REPORT_ID_1, 0x00 };
	int ret, wrote;

	ret = hid_int_ep_write(hdev, report_1, sizeof(report_1), &wrote);

	LOG_DBG("Wrote %d bytes with ret %d", wrote, ret);

	/* Increment reported data */
	report_1[1]++;
}

static void in_ready_cb(void)
{
	k_delayed_work_submit(&delayed_report_send, REPORT_TIMEOUT);
}

static void status_cb(enum usb_dc_status_code status, const u8_t *param)
{
	switch (status) {
	case USB_DC_CONFIGURED:
		in_ready_cb();
		break;
	case USB_DC_SOF:
		break;
	default:
		LOG_DBG("status %u unhandled", status);
		break;
	}
}

static void idle_cb(u16_t report_id)
{
	static u8_t report_1[2] = { 0x00, 0xEB };
	int ret, wrote;

	ret = hid_int_ep_write(hdev, report_1, sizeof(report_1), &wrote);

	LOG_DBG("Idle callback: wrote %d bytes with ret %d", wrote, ret);
}

static void protocol_cb(u8_t protocol)
{
	LOG_DBG("New protocol: %s", protocol == HID_PROTOCOL_BOOT ?
		"boot" : "report");
}

static const struct hid_ops ops = {
	.int_in_ready = in_ready_cb,
	.status_cb = status_cb,
	.on_idle = idle_cb,
	.protocol_change = protocol_cb,
};

void main(void)
{
	LOG_DBG("Starting application");

	k_delayed_work_init(&delayed_report_send, send_report);

#ifndef CONFIG_USB_COMPOSITE_DEVICE
	hdev = device_get_binding(CONFIG_USB_HID_DEVICE_NAME_0);
	if (hdev == NULL) {
		LOG_ERR("Cannot get USB HID Device");
		return;
	}

	LOG_DBG("HID Device: dev %p", hdev);

	usb_hid_register_device(hdev, hid_report_desc, sizeof(hid_report_desc),
				&ops);
	usb_hid_init(hdev);
#endif
}

#ifdef CONFIG_USB_COMPOSITE_DEVICE
static int composite_pre_init(struct device *dev)
{
	hdev = device_get_binding(CONFIG_USB_HID_DEVICE_NAME_0);
	if (hdev == NULL) {
		LOG_ERR("Cannot get USB HID Device");
		return -ENODEV;
	}

	LOG_DBG("HID Device: dev %p", hdev);

	usb_hid_register_device(hdev, hid_report_desc, sizeof(hid_report_desc),
				&ops);

	return usb_hid_init(hdev);
}

SYS_INIT(composite_pre_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
#endif
