/*
 * Copyright (C) 2020 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#import "config.h"
#import "VirtualGamepad.h"

#if USE(APPLE_INTERNAL_SDK)

#import <HID/HIDUserDevice.h>

namespace TestWebKitAPI {

// HID descriptors are an interesting language.
// This is the descriptor dumped from an MFi Nimbus controller, which is fairly representative of a modern controller.
// I got this formatting by dumping the raw descriptor from my device into https://eleccelerator.com/usbdescreqparser/
// In addition to the raw HID language, I've added commentary along the way to further document how this works.
const uint8_t NimbusDescriptor[] = {
    0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
    0x09, 0x05,        // Usage (Game Pad)
    0xA1, 0x01,        // Collection (Application)
    0x09, 0x05,        //   Usage (Game Pad)
    0xA1, 0x02,        //   Collection (Logical)
    0x75, 0x08,        //     Report Size (8) - All reports past this point will be 1 byte per element until Report Size changes.
    0x95, 0x04,        //     Report Count (4) - The upcoming report will have 4 elements, 1 byte each.
    0x15, 0x00,        //     Logical Minimum (0)
    0x26, 0xFF, 0x00,  //     Logical Maximum (255)
    0x35, 0x00,        //     Physical Minimum (0)
    0x46, 0xFF, 0x00,  //     Physical Maximum (255)
    0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
    0x09, 0x90,        //     Usage (D-pad Up) - These 4 d-pad elements will each be a button.
    0x09, 0x92,        //     Usage (D-pad Right)
    0x09, 0x91,        //     Usage (D-pad Down)
    0x09, 0x93,        //     Usage (D-pad Left)
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - Lock in the above input report (4 bytes)
    0x95, 0x08,        //     Report Count (8) - The next report will have 8 elements, 1 byte each (cascaded from above)
    0x05, 0x09,        //     Usage Page (Button)
    0x19, 0x01,        //     Usage Minimum (0x01) - And it will be buttons...
    0x29, 0x08,        //     Usage Maximum (0x08) - 8 of them!
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - Lock in the above input report (8 bytes)
    0x15, 0x00,        //     Logical Minimum (0) - The next elements are pure digital instead of 'analog'
    0x25, 0x01,        //     Logical Maximum (1)
    0x35, 0x00,        //     Physical Minimum (0)
    0x45, 0x01,        //     Physical Maximum (1)
    0x75, 0x01,        //     Report Size (1) - The report size is 1 bit
    0x95, 0x01,        //     Report Count (1) - And there is one such element
    0x05, 0x0C,        //     Usage Page (Consumer)
    0x0A, 0x23, 0x02,  //     Usage (AC Home) - And it is an "AC Home" element, which is basically a fancy button
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - Lock in the above input report (1 bit)
    0x95, 0x07,        //     Report Count (7) - The next report will have 7 elements (of 1 bit each)
    0x81, 0x03,        //     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - And it's constant padding. Lock it in for (7 bits).
    0x15, 0x00,        //     Logical Minimum (0)
    0x25, 0x01,        //     Logical Maximum (1)
    0x35, 0x00,        //     Physical Minimum (0)
    0x45, 0x01,        //     Physical Maximum (1)
    0x75, 0x01,        //     Report Size (1) - The next report will also be 1 bit each (like the AC Home button above)
    0x95, 0x04,        //     Report Count (4) - But there will be 4 of them
    0x05, 0x08,        //     Usage Page (LEDs) - And they are LEDs (This will probably be an output report)
    0x1A, 0x00, 0xFF,  //     Usage Minimum (0xFF00) 0 ...
    0x2A, 0x03, 0xFF,  //     Usage Maximum (0xFF03) ... to 3
    0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) - Lock in the output report of (4 bits)
    0x75, 0x04,        //     Report Size (4) - Also 4 elements in the next report
    0x95, 0x01,        //     Report Count (1) - Also 1 bit each
    0x91, 0x01,        //     Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) - Lock in the constant padding of (4 bits)
    0x15, 0x81,        //     Logical Minimum (-127) - The next elements will have a neg-to-pos output range
    0x25, 0x7F,        //     Logical Maximum (127)
    0x35, 0x81,        //     Physical Minimum (-127)
    0x45, 0x7F,        //     Physical Maximum (127)
    0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
    0x09, 0x01,        //     Usage (Pointer)
    0xA1, 0x00,        //     Collection (Physical)
    0x75, 0x08,        //       Report Size (8) - The report size is 1 byte per element (so that -127 to 127 maps to the 256 possible values)
    0x95, 0x04,        //       Report Count (4) - And there will be 4 of them
    0x09, 0x30,        //       Usage (X) - And they are the first 4 axis usages
    0x09, 0x31,        //       Usage (Y)
    0x09, 0x32,        //       Usage (Z)
    0x09, 0x35,        //       Usage (Rz)
    0x81, 0x02,        //       Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - Lock in the above input report (4 bytes)
    0xC0,              //     End Collection
    0xC0,              //   End Collection
    0xC0,              // End Collection
};

// The total input report size from the above descriptor is:
// 4 bytes + 8 bytes + (1 bit + 7 bits) + 4 bytes = 17 bytes total.
// The total output report size from the above descriptor is:
// (4 bits + 4 bits) == 1 byte total
const size_t NimbusButtonCount = 13;
const size_t NimbusAxisCount = 4;
const size_t NimbusInputReportSize = 17;
const char* NimbusName = "Virtual Nimbus";

// Report layout:
// |b1| |b2| |b3| |b4| |b5| |b6| |b7| |b8| |b9| |b10| |b11| |b12| |b13| |Axis1| |Axis2| |Axis3| |Axis4|

static void publishReportCallback(Vector<float>& buttonValues, Vector<float>& axisValues, HIDUserDevice *userDevice)
{
    uint8_t reportData[NimbusInputReportSize];

    for (size_t i = 0; i < 12; ++i)
        reportData[i] = (uint8_t)(buttonValues[i] * 255);
    reportData[12] = buttonValues[12] == 0.0 ? 0x01 : 0x00;
    for (size_t i = 13; i < 17; ++i)
        reportData[i] = (uint8_t)((int8_t)(axisValues[i - 13] * 127));

    auto nsReportData = adoptNS([[NSData alloc] initWithBytes:reportData length:NimbusInputReportSize]);
    [userDevice handleReport:nsReportData.get() error:nil];
}

GamepadMapping VirtualGamepad::steelSeriesNimbusMapping()
{
    return {
        NimbusDescriptor,
        sizeof(NimbusDescriptor),
        NimbusName,
        HIDVendorID::SteelSeries2,
        HIDProductID::Nimbus,
        NimbusButtonCount,
        NimbusAxisCount,
        publishReportCallback
    };
}

} // namespace TestWebKitAPI

#endif // USE(APPLE_INTERNAL_SDK)
