// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <assert.h>
#include <stdio.h>

#include <hid-parser/item.h>
#include <hid-parser/parser.h>
#include <hid-parser/report.h>
#include <hid-parser/units.h>
#include <hid-parser/usages.h>

#include <unistd.h>
#include <unittest/unittest.h>

// See hid-report-data.cpp for the definitions of the test data.
extern "C" const uint8_t boot_mouse_r_desc[50];
extern "C" const uint8_t hp_mouse_r_desc[46];
extern "C" const uint8_t trinket_r_desc[173];
extern "C" const uint8_t ps3_ds_r_desc[148];
extern "C" const uint8_t acer12_touch_r_desc[660];
extern "C" const uint8_t eve_tablet_r_desc[28];
extern "C" const uint8_t asus_touch_desc[945];
extern "C" const uint8_t eve_touchpad_v2_r_desc[560];

namespace {
struct Stats {
    int input_count;
    int collection[2];
};

size_t ItemizeHIDReportDesc(const uint8_t* rpt_desc, size_t desc_len, Stats* stats) {
    const uint8_t* buf = rpt_desc;
    size_t len = desc_len;
    while (len > 0) {
        size_t actual = 0;
        auto item = hid::Item::ReadNext(buf, len, &actual);
        if ((actual > len) || (actual == 0))
            break;

        if (item.tag() == hid::Item::Tag::kEndCollection)
            stats->collection[1]++;
        else if (item.tag() == hid::Item::Tag::kCollection)
            stats->collection[0]++;

        if (item.type() == hid::Item::Type::kMain && item.tag() == hid::Item::Tag::kInput)
            stats->input_count++;

        len -= actual;
        buf += actual;
    }

    return (desc_len - len);
}

} // namespace.

static bool itemize_acer12_rpt1() {
    BEGIN_TEST;

    Stats stats = {};
    auto len = sizeof(acer12_touch_r_desc);
    auto consumed = ItemizeHIDReportDesc(acer12_touch_r_desc, len, &stats);

    ASSERT_EQ(consumed, len);
    ASSERT_EQ(stats.input_count, 45);
    ASSERT_EQ(stats.collection[0], 13);
    ASSERT_EQ(stats.collection[1], 13);

    END_TEST;
}

static bool itemize_eve_tablet_rpt() {
    BEGIN_TEST;

    Stats stats = {};
    auto len = sizeof(eve_tablet_r_desc);
    auto consumed = ItemizeHIDReportDesc(eve_tablet_r_desc, len, &stats);

    ASSERT_EQ(consumed, len);
    ASSERT_EQ(stats.input_count, 2);
    ASSERT_EQ(stats.collection[0], 1);
    ASSERT_EQ(stats.collection[1], 1);

    END_TEST;
}

static bool parse_boot_mouse() {
    BEGIN_TEST;

    hid::DeviceDescriptor* dev = nullptr;
    auto res = hid::ParseReportDescriptor(
        boot_mouse_r_desc, sizeof(boot_mouse_r_desc), &dev);

    ASSERT_EQ(res, hid::ParseResult::kParseOk);

    // A single report with id zero, this means no report id.
    ASSERT_EQ(dev->rep_count, 1u);
    EXPECT_EQ(dev->report[0].report_id, 0);

    // The only report has 6 fields and is 32 bits long.
    EXPECT_EQ(dev->report[0].input_count, 6);
    EXPECT_EQ(dev->report[0].input_byte_sz, 3);
    const auto fields = dev->report[0].input_fields;

    // All fields are input type with report id = 0.
    for (uint8_t ix = 0; ix != dev->report[0].input_count; ++ix) {
        EXPECT_EQ(fields[ix].report_id, 0);
        EXPECT_EQ(fields[ix].type, hid::kInput);
    }

    // First 3 fields are the buttons, with usages 1, 2, 3, in the button page.
    auto expected_flags = hid::kData | hid::kAbsolute | hid::kScalar;

    for (uint8_t ix = 0; ix != 3; ++ix) {
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kButton);
        EXPECT_EQ(fields[ix].attr.usage.usage, uint32_t(ix + 1));
        EXPECT_EQ(fields[ix].attr.bit_sz, 1);
        EXPECT_EQ(fields[ix].attr.offset, ix);
        EXPECT_EQ(fields[ix].attr.logc_mm.min, 0);
        EXPECT_EQ(fields[ix].attr.logc_mm.max, 1);
        EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags);
    }

    // Next field is 5 bits constant. Aka padding.
    EXPECT_EQ(fields[3].attr.bit_sz, 5);
    EXPECT_EQ(fields[3].attr.offset, 3);
    EXPECT_EQ(hid::kConstant & fields[3].flags, hid::kConstant);

    // Next comes 'X' field, 8 bits data, relative.
    expected_flags = hid::kData | hid::kRelative | hid::kScalar;

    EXPECT_EQ(fields[4].attr.usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(fields[4].attr.usage.usage, hid::usage::GenericDesktop::kX);
    EXPECT_EQ(fields[4].attr.bit_sz, 8);
    EXPECT_EQ(fields[4].attr.offset, 8);
    EXPECT_EQ(fields[4].attr.logc_mm.min, -127);
    EXPECT_EQ(fields[4].attr.logc_mm.max, 127);
    EXPECT_EQ(fields[4].attr.phys_mm.min, -127);
    EXPECT_EQ(fields[4].attr.phys_mm.max, 127);
    EXPECT_EQ(expected_flags & fields[4].flags, expected_flags);

    // Last comes 'Y' field, same as 'X'.
    EXPECT_EQ(fields[5].attr.usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(fields[5].attr.usage.usage, hid::usage::GenericDesktop::kY);
    EXPECT_EQ(fields[5].attr.bit_sz, 8);
    EXPECT_EQ(fields[5].attr.offset, 16);
    EXPECT_EQ(fields[5].attr.logc_mm.min, -127);
    EXPECT_EQ(fields[5].attr.logc_mm.max, 127);
    EXPECT_EQ(fields[5].attr.phys_mm.min, -127);
    EXPECT_EQ(fields[5].attr.phys_mm.max, 127);
    EXPECT_EQ(expected_flags & fields[4].flags, expected_flags);

    // Now test the collections.
    // Inner collection is physical GeneticDesktop|Pointer.
    auto collection = fields[0].col;
    ASSERT_TRUE(collection != nullptr);
    EXPECT_EQ(collection->type, hid::CollectionType::kPhysical);
    EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kPointer);

    // Outer collection is the application.
    collection = collection->parent;
    ASSERT_TRUE(collection != nullptr);
    EXPECT_EQ(collection->type, hid::CollectionType::kApplication);
    EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kMouse);

    // No parent collection.
    EXPECT_TRUE(collection->parent == nullptr);

    // Test the helpers.
    auto app_col = hid::GetAppCollection(&dev->report[0].input_fields[0]);
    EXPECT_EQ(app_col, collection);

    hid::FreeDeviceDescriptor(dev);
    END_TEST;
}

static bool parse_hp_mouse() {
    BEGIN_TEST;

    hid::DeviceDescriptor* dev = nullptr;
    auto res = hid::ParseReportDescriptor(
        hp_mouse_r_desc, sizeof(hp_mouse_r_desc), &dev);

    ASSERT_EQ(res, hid::ParseResult::kParseOk);

    // A single report with id zero, this means no report id.
    ASSERT_EQ(dev->rep_count, 1u);
    EXPECT_EQ(dev->report[0].report_id, 0);

    // The only report has 11 fields.
    EXPECT_EQ(dev->report[0].input_count, 11);
    const auto fields = dev->report[0].input_fields;

    // All fields are input type with report id = 0.
    for (uint8_t ix = 0; ix != dev->report[0].input_count; ++ix) {
        EXPECT_EQ(fields[ix].report_id, 0);
        EXPECT_EQ(fields[ix].type, hid::kInput);
    }

    // First 8 fields are the buttons, with usages 1, 2, 3, 3 .. 3 in the button page.
    auto expected_flags = hid::kData | hid::kAbsolute | hid::kScalar;

    for (uint8_t ix = 0; ix != 8; ++ix) {
        auto usage = (ix < 3) ? uint32_t(ix + 1) : uint32_t(3);
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kButton);
        EXPECT_EQ(fields[ix].attr.usage.usage, usage);
        EXPECT_EQ(fields[ix].attr.bit_sz, 1);
        EXPECT_EQ(fields[ix].attr.logc_mm.min, 0);
        EXPECT_EQ(fields[ix].attr.logc_mm.max, 1);
        EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags);
    }

    // Next comes 'X' field, 8 bits data, relative.
    expected_flags = hid::kData | hid::kRelative | hid::kScalar;

    EXPECT_EQ(fields[8].attr.usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(fields[8].attr.usage.usage, hid::usage::GenericDesktop::kX);
    EXPECT_EQ(fields[8].attr.bit_sz, 8);
    EXPECT_EQ(fields[8].attr.logc_mm.min, -127);
    EXPECT_EQ(fields[8].attr.logc_mm.max, 127);
    EXPECT_EQ(fields[8].attr.phys_mm.min, -127);
    EXPECT_EQ(fields[8].attr.phys_mm.max, 127);
    EXPECT_EQ(expected_flags & fields[8].flags, expected_flags);

    // Next comes 'Y' field, same as 'X'.
    EXPECT_EQ(fields[9].attr.usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(fields[9].attr.usage.usage, hid::usage::GenericDesktop::kY);
    EXPECT_EQ(fields[9].attr.bit_sz, 8);
    EXPECT_EQ(fields[9].attr.logc_mm.min, -127);
    EXPECT_EQ(fields[9].attr.logc_mm.max, 127);
    EXPECT_EQ(fields[9].attr.phys_mm.min, -127);
    EXPECT_EQ(fields[9].attr.phys_mm.max, 127);
    EXPECT_EQ(expected_flags & fields[9].flags, expected_flags);

    // Last comes 'Wheel' field.
    EXPECT_EQ(fields[10].attr.usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(fields[10].attr.usage.usage, hid::usage::GenericDesktop::kWheel);
    EXPECT_EQ(fields[10].attr.bit_sz, 8);
    EXPECT_EQ(fields[10].attr.logc_mm.min, -127);
    EXPECT_EQ(fields[10].attr.logc_mm.max, 127);
    EXPECT_EQ(fields[10].attr.phys_mm.min, -127);
    EXPECT_EQ(fields[10].attr.phys_mm.max, 127);
    EXPECT_EQ(expected_flags & fields[10].flags, expected_flags);

    // Now test the collections.
    // Inner collection is physical GeneticDesktop|Pointer.
    auto collection = fields[0].col;
    ASSERT_TRUE(collection != nullptr);
    EXPECT_EQ(collection->type, hid::CollectionType::kPhysical);
    EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kPointer);

    // Outer collection is the application.
    collection = collection->parent;
    ASSERT_TRUE(collection != nullptr);
    EXPECT_EQ(collection->type, hid::CollectionType::kApplication);
    EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kMouse);

    // No parent collection.
    EXPECT_TRUE(collection->parent == nullptr);

    hid::FreeDeviceDescriptor(dev);
    END_TEST;
}

static bool parse_adaf_trinket() {
    BEGIN_TEST;

    hid::DeviceDescriptor* dev = nullptr;
    auto res = hid::ParseReportDescriptor(
        trinket_r_desc, sizeof(trinket_r_desc), &dev);

    ASSERT_EQ(res, hid::ParseResult::kParseOk);

    // Four different reports
    ASSERT_EQ(dev->rep_count, 4u);

    //////////////////////////////////////////////////////////////////////////////////
    // First report is the same as boot_mouse, except for the report id.
    EXPECT_EQ(dev->report[0].report_id, 1);
    ASSERT_EQ(dev->report[0].input_count, 6);
    EXPECT_EQ(dev->report[0].input_byte_sz, 4);
    const hid::ReportField* fields = dev->report[0].input_fields;

    // All fields are scalar input type with report id = 1.
    for (uint8_t ix = 0; ix != dev->report[0].input_count; ++ix) {
        EXPECT_EQ(fields[ix].report_id, 1);
        EXPECT_EQ(fields[ix].type, hid::kInput);
        EXPECT_EQ(hid::kScalar & fields[ix].flags, hid::kScalar);
    }

    // First 3 fields are the buttons, with usages 1, 2, 3, in the button page.
    auto expected_flags = hid::kData | hid::kAbsolute;

    for (uint8_t ix = 0; ix != 3; ++ix) {
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kButton);
        EXPECT_EQ(fields[ix].attr.usage.usage, uint32_t(ix + 1));
        EXPECT_EQ(fields[ix].attr.bit_sz, 1);
        EXPECT_EQ(fields[ix].attr.offset, 8u + ix);
        EXPECT_EQ(fields[ix].attr.logc_mm.min, 0);
        EXPECT_EQ(fields[ix].attr.logc_mm.max, 1);
        EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags);
    }

    // Next field is 5 bits constant. Aka padding.
    EXPECT_EQ(fields[3].attr.bit_sz, 5);
    EXPECT_EQ(hid::kConstant & fields[3].flags, hid::kConstant);

    // Next comes 'X' field, 8 bits data, relative.
    expected_flags = hid::kData | hid::kRelative;

    EXPECT_EQ(fields[4].attr.usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(fields[4].attr.usage.usage, hid::usage::GenericDesktop::kX);
    EXPECT_EQ(fields[4].attr.bit_sz, 8);
    EXPECT_EQ(fields[4].attr.offset, 16);
    EXPECT_EQ(fields[4].attr.logc_mm.min, -127);
    EXPECT_EQ(fields[4].attr.logc_mm.max, 127);
    EXPECT_EQ(expected_flags & fields[4].flags, expected_flags);

    // Last comes 'Y' field, same as 'X'.
    EXPECT_EQ(fields[5].attr.usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(fields[5].attr.usage.usage, hid::usage::GenericDesktop::kY);
    EXPECT_EQ(fields[5].attr.bit_sz, 8);
    EXPECT_EQ(fields[5].attr.offset, 24);
    EXPECT_EQ(fields[5].attr.logc_mm.min, -127);
    EXPECT_EQ(fields[5].attr.logc_mm.max, 127);
    EXPECT_EQ(expected_flags & fields[4].flags, expected_flags);

    // Now test the collections.
    // Inner collection is physical GeneticDesktop|Pointer.
    auto collection = fields[0].col;
    ASSERT_TRUE(collection != nullptr);
    EXPECT_EQ(collection->type, hid::CollectionType::kPhysical);
    EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kPointer);

    // Outer collection is the application.
    collection = collection->parent;
    ASSERT_TRUE(collection != nullptr);
    EXPECT_EQ(collection->type, hid::CollectionType::kApplication);
    EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kMouse);

    // No parent collection.
    EXPECT_TRUE(collection->parent == nullptr);

    //////////////////////////////////////////////////////////////////////////////////
    // Second  report is a keyboard with 20 fields and is 72 bits long.
    EXPECT_EQ(dev->report[1].report_id, 2);
    ASSERT_EQ(dev->report[1].input_count, 14);
    EXPECT_EQ(dev->report[1].input_byte_sz, 8);
    ASSERT_EQ(dev->report[1].output_count, 6);
    EXPECT_EQ(dev->report[1].output_byte_sz, 2);

    const hid::ReportField* output_fields = dev->report[1].output_fields;
    fields = dev->report[1].input_fields;

    // First 8 are input bits with usages 0xe0 to 0xe7 on the keyboard page.
    expected_flags = hid::kData | hid::kAbsolute | hid::kScalar;

    for (uint8_t ix = 0; ix != 8; ++ix) {
        EXPECT_EQ(fields[ix].type, hid::kInput);
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kKeyboardKeypad);
        EXPECT_EQ(fields[ix].attr.usage.usage, uint32_t(ix + 0xe0));
        EXPECT_EQ(fields[ix].attr.bit_sz, 1);
        EXPECT_EQ(fields[ix].attr.offset, 8u + ix);
        EXPECT_EQ(fields[ix].attr.logc_mm.min, 0);
        EXPECT_EQ(fields[ix].attr.logc_mm.max, 1);
        EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags);
    }

    // Next field is 8 bits padding (input).
    EXPECT_EQ(fields[8].attr.bit_sz, 8);
    EXPECT_EQ(fields[8].attr.offset, 16);
    EXPECT_EQ(fields[8].type, hid::kInput);
    EXPECT_EQ(hid::kConstant & fields[8].flags, hid::kConstant);

    // Next 5 fields are byte-sized key input array.
    expected_flags = hid::kData | hid::kAbsolute | hid::kArray;

    for (uint8_t ix = 9; ix != 14; ++ix) {
        EXPECT_EQ(fields[ix].type, hid::kInput);
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kKeyboardKeypad);
        EXPECT_EQ(fields[ix].attr.bit_sz, 8);
        EXPECT_EQ(fields[ix].attr.offset, 24u + 8u * (ix - 9u));
        EXPECT_EQ(fields[ix].attr.usage.usage, 0);
        EXPECT_EQ(fields[ix].attr.logc_mm.min, 0);
        EXPECT_EQ(fields[ix].attr.logc_mm.max, 164);
        EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags);
    }

    // Test the output fields (LED bits output, with usages NumLock(1) to Kana(5)).
    auto led_usage = static_cast<uint16_t>(hid::usage::LEDs::kNumLock);
    expected_flags = hid::kData | hid::kAbsolute | hid::kScalar;

    for (uint8_t ix = 0; ix != 5; ++ix) {
        EXPECT_EQ(output_fields[ix].type, hid::kOutput);
        EXPECT_EQ(output_fields[ix].attr.usage.page, hid::usage::Page::kLEDs);
        EXPECT_EQ(output_fields[ix].attr.bit_sz, 1);
        EXPECT_EQ(output_fields[ix].attr.offset, 8u + ix);
        EXPECT_EQ(output_fields[ix].attr.usage.usage, led_usage++);
        EXPECT_EQ(expected_flags & output_fields[ix].flags, expected_flags);
    }

    // Next field is 3 bits padding (output).
    EXPECT_EQ(output_fields[5].attr.bit_sz, 3);
    EXPECT_EQ(output_fields[5].attr.offset, 13u);
    EXPECT_EQ(output_fields[5].type, hid::kOutput);
    EXPECT_EQ(hid::kConstant & output_fields[5].flags, hid::kConstant);

    // All fields belong to the same collection
    collection = fields[0].col;

    for (uint8_t ix = 1; ix != 20; ++ix) {
        EXPECT_TRUE(fields[ix].col == collection);
    }

    ASSERT_TRUE(collection != nullptr);
    EXPECT_EQ(collection->type, hid::CollectionType::kApplication);
    EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kKeyboard);
    // No parent collection.
    EXPECT_TRUE(collection->parent == nullptr);

    //////////////////////////////////////////////////////////////////////////////////
    // Third report, single 16 bit input array field (consumer control).  24 bits long.
    EXPECT_EQ(dev->report[2].report_id, 3);
    ASSERT_EQ(dev->report[2].input_count, 1);
    EXPECT_EQ(dev->report[2].input_byte_sz, 3);

    fields = dev->report[2].input_fields;

    expected_flags = hid::kData | hid::kAbsolute | hid::kArray;

    EXPECT_EQ(fields[0].type, hid::kInput);
    EXPECT_EQ(fields[0].attr.usage.page, hid::usage::Page::kConsumer);
    EXPECT_EQ(fields[0].attr.usage.usage, 0);
    EXPECT_EQ(fields[0].attr.logc_mm.min, 0);
    EXPECT_EQ(fields[0].attr.logc_mm.max, 572);
    EXPECT_EQ(fields[0].attr.bit_sz, 16);
    EXPECT_EQ(fields[0].attr.offset, 8);
    EXPECT_EQ(expected_flags & fields[0].flags, expected_flags);

    collection = fields[0].col;
    ASSERT_TRUE(collection != nullptr);
    EXPECT_EQ(collection->type, hid::CollectionType::kApplication);
    EXPECT_EQ(collection->usage.page, hid::usage::Page::kConsumer);
    EXPECT_EQ(collection->usage.usage, hid::usage::Consumer::kConsumerControl);
    // No parent collection.
    EXPECT_TRUE(collection->parent == nullptr);

    //////////////////////////////////////////////////////////////////////////////////
    // Fourth report is a 2 bit input (system control: sleep, wake-up, power-down)
    // 16 bits in total.

    EXPECT_EQ(dev->report[3].report_id, 4);
    ASSERT_EQ(dev->report[3].input_count, 2);
    ASSERT_EQ(dev->report[3].input_byte_sz, 2);

    fields = dev->report[3].input_fields;

    // First field is a 2 bit input array.
    expected_flags = hid::kData | hid::kAbsolute | hid::kArray;

    EXPECT_EQ(fields[0].type, hid::kInput);
    EXPECT_EQ(fields[0].attr.usage.page, hid::usage::Page::kGenericDesktop);
    // TODO(cpu): The |usage.usage| as parsed is incorrect. In this particular
    // case as the array input 1,2,3 should map to 0x82, 0x81, 0x83 which is not currently
    // supported in the model.
    EXPECT_EQ(fields[0].attr.usage.usage, hid::usage::GenericDesktop::kSystemSleep);
    EXPECT_EQ(fields[0].attr.logc_mm.min, 1);
    EXPECT_EQ(fields[0].attr.logc_mm.max, 3);
    EXPECT_EQ(fields[0].attr.bit_sz, 2);
    EXPECT_EQ(fields[0].attr.offset, 8);
    EXPECT_EQ(expected_flags & fields[0].flags, expected_flags);

    // Last field is 6 bits padding (output).
    EXPECT_EQ(fields[1].attr.bit_sz, 6);
    EXPECT_EQ(fields[1].attr.offset, 10);
    EXPECT_EQ(fields[1].type, hid::kInput);
    EXPECT_EQ(hid::kConstant & fields[1].flags, hid::kConstant);

    collection = fields[0].col;
    ASSERT_TRUE(collection != nullptr);
    EXPECT_EQ(collection->type, hid::CollectionType::kApplication);
    EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kSystemControl);
    // No parent collection.
    EXPECT_TRUE(collection->parent == nullptr);

    hid::FreeDeviceDescriptor(dev);
    END_TEST;
}

static bool parse_ps3_controller() {
    BEGIN_TEST;

    hid::DeviceDescriptor* dev = nullptr;
    auto res = hid::ParseReportDescriptor(
        ps3_ds_r_desc, sizeof(ps3_ds_r_desc), &dev);

    ASSERT_EQ(res, hid::ParseResult::kParseOk);
    // Four different reports
    ASSERT_EQ(dev->rep_count, 4u);

    //////////////////////////////////////////////////////////////////////////////////
    // First report has 172 fields!!  1160 bits long!!!
    EXPECT_EQ(dev->report[0].report_id, 1);

    ASSERT_EQ(dev->report[0].input_count, 76);
    ASSERT_EQ(dev->report[0].input_byte_sz, 49);

    ASSERT_EQ(dev->report[0].output_count, 48);
    ASSERT_EQ(dev->report[0].output_byte_sz, 49);

    ASSERT_EQ(dev->report[0].feature_count, 48);
    ASSERT_EQ(dev->report[0].feature_byte_sz, 49);
    const hid::ReportField* fields = dev->report[0].input_fields;
    const hid::ReportField* output_fields = dev->report[0].output_fields;
    const hid::ReportField* feature_fields = dev->report[0].feature_fields;

    // First field is 8 bits, constant GenericDesktop page, but no usage described.
    // being it is a version number?
    auto expected_flags = hid::kConstant | hid::kAbsolute | hid::kScalar;

    EXPECT_EQ(fields[0].type, hid::kInput);
    EXPECT_EQ(fields[0].attr.usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(fields[0].attr.usage.usage, 0);
    EXPECT_EQ(fields[0].attr.logc_mm.min, 0);
    EXPECT_EQ(fields[0].attr.logc_mm.max, 255);
    EXPECT_EQ(fields[0].attr.bit_sz, 8);
    EXPECT_EQ(fields[0].attr.offset, 8);
    EXPECT_EQ(expected_flags & fields[0].flags, expected_flags);

    // Next 19 fields are one-bit input representing the buttons.
    expected_flags = hid::kData | hid::kAbsolute | hid::kScalar;

    for (uint8_t ix = 1; ix != 20; ++ix) {
        EXPECT_EQ(fields[ix].type, hid::kInput);
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kButton);
        EXPECT_EQ(fields[ix].attr.usage.usage, ix);
        EXPECT_EQ(fields[ix].attr.bit_sz, 1);
        EXPECT_EQ(fields[ix].attr.offset, 16u + (ix - 1u));
        EXPECT_EQ(fields[ix].attr.logc_mm.min, 0);
        EXPECT_EQ(fields[ix].attr.logc_mm.max, 1);
        EXPECT_EQ(fields[ix].attr.phys_mm.min, 0);
        EXPECT_EQ(fields[ix].attr.phys_mm.max, 1);
        EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags);
    }

    // The next 13 fields are 13 bits of constant, vendor-defined. Probably padding.
    for (uint8_t ix = 20; ix != 33; ++ix) {
        EXPECT_EQ(fields[ix].type, hid::kInput);
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kVendorDefinedStart);
        EXPECT_EQ(fields[ix].attr.usage.usage, 0);
        EXPECT_EQ(fields[ix].attr.bit_sz, 1);
        EXPECT_EQ(fields[ix].attr.offset, 35u + (ix - 20u));
        EXPECT_EQ(hid::kConstant & fields[ix].flags, hid::kConstant);
    }

    expected_flags = hid::kData | hid::kAbsolute | hid::kScalar;

    // Next four 8-bit input fields are X,Y, Z and Rz.
    for (uint8_t ix = 33; ix != 37; ++ix) {
        EXPECT_EQ(fields[ix].type, hid::kInput);
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kGenericDesktop);
        EXPECT_EQ(fields[ix].attr.bit_sz, 8);
        EXPECT_EQ(fields[ix].attr.offset, 48u + 8u * (ix - 33u));
        EXPECT_EQ(fields[ix].attr.logc_mm.min, 0);
        EXPECT_EQ(fields[ix].attr.logc_mm.max, 255);
        EXPECT_EQ(fields[ix].attr.phys_mm.min, 0);
        EXPECT_EQ(fields[ix].attr.phys_mm.max, 255);
        EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags);
    }

    EXPECT_EQ(fields[33].attr.usage.usage, hid::usage::GenericDesktop::kX);
    EXPECT_EQ(fields[34].attr.usage.usage, hid::usage::GenericDesktop::kY);
    EXPECT_EQ(fields[35].attr.usage.usage, hid::usage::GenericDesktop::kZ);
    EXPECT_EQ(fields[36].attr.usage.usage, hid::usage::GenericDesktop::kRz);

    // Next 39 fields are input, 8-bit pointer scalar data.
    for (uint8_t ix = 37; ix != 76; ++ix) {
        EXPECT_EQ(fields[ix].type, hid::kInput);
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kGenericDesktop);
        EXPECT_EQ(fields[ix].attr.usage.usage, hid::usage::GenericDesktop::kPointer);
        EXPECT_EQ(fields[ix].attr.bit_sz, 8);
        EXPECT_EQ(fields[ix].attr.offset, 80u + 8u * (ix - 37u));
        EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags);
    }

    // Test the 48 8-bit scalar output pointer data.
    for (uint8_t ix = 0; ix != 48; ++ix) {
        EXPECT_EQ(output_fields[ix].type, hid::kOutput);
        EXPECT_EQ(output_fields[ix].attr.usage.page, hid::usage::Page::kGenericDesktop);
        EXPECT_EQ(output_fields[ix].attr.usage.usage, hid::usage::GenericDesktop::kPointer);
        EXPECT_EQ(output_fields[ix].attr.bit_sz, 8);
        EXPECT_EQ(output_fields[ix].attr.offset, 8u + 8u * ix);
        EXPECT_EQ(expected_flags & output_fields[ix].flags, expected_flags);
    }

    // Test the 48 8-bit scalar feature pointer data.
    for (uint8_t ix = 0; ix != 48; ++ix) {
        EXPECT_EQ(feature_fields[ix].type, hid::kFeature);
        EXPECT_EQ(feature_fields[ix].attr.usage.page, hid::usage::Page::kGenericDesktop);
        EXPECT_EQ(feature_fields[ix].attr.usage.usage, hid::usage::GenericDesktop::kPointer);
        EXPECT_EQ(feature_fields[ix].attr.bit_sz, 8);
        EXPECT_EQ(feature_fields[ix].attr.offset, 8u + 8u * (ix));
        EXPECT_EQ(expected_flags & feature_fields[ix].flags, expected_flags);
    }

    //////////////////////////////////////////////////////////////////////////////////
    // Second report has 48 fields. It is pretty much identical to last 48 fields
    // of the first report.  392 bits long.

    EXPECT_EQ(dev->report[1].report_id, 2);
    ASSERT_EQ(dev->report[1].feature_count, 48);
    ASSERT_EQ(dev->report[2].feature_byte_sz, 49);
    feature_fields = dev->report[1].feature_fields;

    expected_flags = hid::kData | hid::kAbsolute | hid::kScalar;

    for (uint8_t ix = 0; ix != 48; ++ix) {
        EXPECT_EQ(feature_fields[ix].type, hid::kFeature);
        EXPECT_EQ(feature_fields[ix].attr.usage.page, hid::usage::Page::kGenericDesktop);
        EXPECT_EQ(feature_fields[ix].attr.usage.usage, hid::usage::GenericDesktop::kPointer);
        EXPECT_EQ(feature_fields[ix].attr.bit_sz, 8);
        EXPECT_EQ(feature_fields[ix].attr.offset, 8u + 8u * ix);
        EXPECT_EQ(expected_flags & feature_fields[ix].flags, expected_flags);
    }

    //////////////////////////////////////////////////////////////////////////////////
    // Third report is same as the second one except for report id.

    EXPECT_EQ(dev->report[2].report_id, 0xee);
    ASSERT_EQ(dev->report[2].feature_count, 48);
    ASSERT_EQ(dev->report[2].feature_byte_sz, 49);
    feature_fields = dev->report[2].feature_fields;

    expected_flags = hid::kData | hid::kAbsolute | hid::kScalar;

    for (uint8_t ix = 0; ix != 48; ++ix) {
        EXPECT_EQ(feature_fields[ix].type, hid::kFeature);
        EXPECT_EQ(feature_fields[ix].attr.usage.page, hid::usage::Page::kGenericDesktop);
        EXPECT_EQ(feature_fields[ix].attr.usage.usage, hid::usage::GenericDesktop::kPointer);
        EXPECT_EQ(feature_fields[ix].attr.bit_sz, 8);
        EXPECT_EQ(feature_fields[ix].attr.offset, 8u + 8u * ix);
        EXPECT_EQ(expected_flags & feature_fields[ix].flags, expected_flags);
    }

    //////////////////////////////////////////////////////////////////////////////////
    // Fourth report is same as the second one except for report id.

    EXPECT_EQ(dev->report[3].report_id, 0xef);
    ASSERT_EQ(dev->report[2].feature_count, 48);
    ASSERT_EQ(dev->report[2].feature_byte_sz, 49);
    feature_fields = dev->report[3].feature_fields;

    expected_flags = hid::kData | hid::kAbsolute | hid::kScalar;

    for (uint8_t ix = 0; ix != 48; ++ix) {
        EXPECT_EQ(feature_fields[ix].type, hid::kFeature);
        EXPECT_EQ(feature_fields[ix].attr.usage.page, hid::usage::Page::kGenericDesktop);
        EXPECT_EQ(feature_fields[ix].attr.usage.usage, hid::usage::GenericDesktop::kPointer);
        EXPECT_EQ(feature_fields[ix].attr.bit_sz, 8);
        EXPECT_EQ(feature_fields[ix].attr.offset, 8u + 8u * ix);
        EXPECT_EQ(expected_flags & feature_fields[ix].flags, expected_flags);
    }

    // Collections test
    //
    // In the first report, The X,Y,Z, Rz fields are in a 3-level
    // deep collection physical -> logical -> app. Test that.
    auto collection = dev->report[0].input_fields[33].col;

    ASSERT_TRUE(collection != nullptr);
    EXPECT_EQ(collection->type, hid::CollectionType::kPhysical);
    EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kPointer);

    collection = collection->parent;
    ASSERT_TRUE(collection != nullptr);
    EXPECT_EQ(collection->type, hid::CollectionType::kLogical);
    EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(collection->usage.usage, 0);

    collection = collection->parent;
    ASSERT_TRUE(collection != nullptr);
    EXPECT_EQ(collection->type, hid::CollectionType::kApplication);
    EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kJoystick);
    EXPECT_TRUE(collection->parent == nullptr);

    // The second report first field is in a logical -> app collection.
    collection = dev->report[1].input_fields[0].col;

    ASSERT_TRUE(collection != nullptr);
    EXPECT_EQ(collection->type, hid::CollectionType::kLogical);
    EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(collection->usage.usage, 0);

    collection = collection->parent;
    ASSERT_TRUE(collection != nullptr);
    EXPECT_EQ(collection->type, hid::CollectionType::kApplication);
    EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kJoystick);
    EXPECT_TRUE(collection->parent == nullptr);

    // The third report is the same as the second. This seems a trivial test
    // but previous parsers failed this one.
    collection = dev->report[2].input_fields[0].col;

    ASSERT_TRUE(collection != nullptr);
    EXPECT_EQ(collection->type, hid::CollectionType::kLogical);
    EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(collection->usage.usage, 0);

    collection = collection->parent;
    ASSERT_TRUE(collection != nullptr);
    EXPECT_EQ(collection->type, hid::CollectionType::kApplication);
    EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kJoystick);
    EXPECT_TRUE(collection->parent == nullptr);

    hid::FreeDeviceDescriptor(dev);
    END_TEST;
}

static bool parse_acer12_touch() {
    BEGIN_TEST;

    hid::DeviceDescriptor* dd = nullptr;
    auto res = hid::ParseReportDescriptor(
        acer12_touch_r_desc, sizeof(acer12_touch_r_desc), &dd);

    EXPECT_EQ(res, hid::ParseResult::kParseOk);

    hid::FreeDeviceDescriptor(dd);
    END_TEST;
}

static bool parse_eve_tablet() {
    BEGIN_TEST;

    hid::DeviceDescriptor* dev = nullptr;
    auto res = hid::ParseReportDescriptor(
        eve_tablet_r_desc, sizeof(eve_tablet_r_desc), &dev);

    EXPECT_EQ(res, hid::ParseResult::kParseOk);

    // A single report, no id.
    ASSERT_EQ(dev->rep_count, 1u);
    EXPECT_EQ(dev->report[0].report_id, 0);

    // Report has two fields.  8 bits long
    ASSERT_EQ(dev->report[0].input_count, 2u);
    ASSERT_EQ(dev->report[0].input_byte_sz, 1u);

    const hid::ReportField* fields = dev->report[0].input_fields;

    // First field is 1 bit, (tablet / no-tablet)
    auto expected_flags = hid::kData | hid::kAbsolute | hid::kScalar;

    EXPECT_EQ(fields[0].type, hid::kInput);
    EXPECT_EQ(fields[0].attr.usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(fields[0].attr.usage.usage, 0xff000001);
    EXPECT_EQ(fields[0].attr.bit_sz, 1);
    EXPECT_EQ(fields[0].attr.offset, 0);
    EXPECT_EQ(expected_flags & fields[0].flags, expected_flags);

    // Second field is padding, 7 bits.
    expected_flags = hid::kConstant | hid::kAbsolute | hid::kScalar;

    EXPECT_EQ(fields[1].type, hid::kInput);
    EXPECT_EQ(fields[1].attr.usage.page, hid::usage::Page::kGenericDesktop);
    EXPECT_EQ(fields[1].attr.usage.usage, 0);
    EXPECT_EQ(fields[1].attr.bit_sz, 7);
    EXPECT_EQ(fields[1].attr.offset, 1);
    EXPECT_EQ(expected_flags & fields[1].flags, expected_flags);

    hid::FreeDeviceDescriptor(dev);
    END_TEST;
}

static bool parse_asus_touch() {
    BEGIN_TEST;
    hid::DeviceDescriptor* dev = nullptr;
    auto res = hid::ParseReportDescriptor(asus_touch_desc, sizeof(asus_touch_desc), &dev);
    ASSERT_EQ(res, hid::ParseResult::kParseOk);
    END_TEST;
}

bool parse_eve_touchpad_v2() {
    BEGIN_TEST;
    hid::DeviceDescriptor* dev = nullptr;
    auto res = hid::ParseReportDescriptor(eve_touchpad_v2_r_desc,
                                          sizeof(eve_touchpad_v2_r_desc), &dev);
    ASSERT_EQ(res, hid::ParseResult::kParseOk);
    // Check that we have one main collection.
    EXPECT_EQ(dev->rep_count, 1);

    EXPECT_EQ(dev->report[0].report_id, 1);
    EXPECT_EQ(dev->report[0].input_count, 47);

    const hid::ReportField* fields = dev->report[0].input_fields;

    uint8_t ix = 0;

    // First report is a button.
    EXPECT_EQ(fields[ix].report_id, 1);
    EXPECT_EQ(fields[ix].type, hid::kInput);
    EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kButton);
    EXPECT_EQ(fields[ix].attr.bit_sz, 1);
    ++ix;

    // Second report is a digitizer.
    EXPECT_EQ(fields[ix].report_id, 1);
    EXPECT_EQ(fields[ix].type, hid::kInput);
    EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kDigitizer);
    EXPECT_EQ(fields[ix].attr.bit_sz, 7);
    ++ix;

    // Here are the finger collections. There are 10 items per finger.
    for (int finger = 0; finger != 5; ++finger) {
        char err_msg[50];
        sprintf(err_msg, "Failed on Finger %d\n", finger);

        EXPECT_EQ(fields[ix].type, hid::kInput);
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kDigitizer, err_msg);
        EXPECT_EQ(fields[ix].attr.usage.usage, hid::usage::Digitizer::kTipSwitch, err_msg);
        EXPECT_EQ(fields[ix].attr.bit_sz, 1);
        ++ix;

        EXPECT_EQ(fields[ix].type, hid::kInput);
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kDigitizer, err_msg);
        EXPECT_EQ(fields[ix].attr.usage.usage, hid::usage::Digitizer::kInRange, err_msg);
        EXPECT_EQ(fields[ix].attr.bit_sz, 7);
        ++ix;

        EXPECT_EQ(fields[ix].type, hid::kInput);
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kDigitizer, err_msg);
        EXPECT_EQ(fields[ix].attr.usage.usage, 0x51, err_msg);
        EXPECT_EQ(fields[ix].attr.bit_sz, 16);
        ++ix;

        // The X coordinate.
        EXPECT_EQ(fields[ix].type, hid::kInput);
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kGenericDesktop, err_msg);
        EXPECT_EQ(fields[ix].attr.usage.usage, hid::usage::GenericDesktop::kX, err_msg);
        EXPECT_EQ(fields[ix].attr.phys_mm.min, 0, err_msg);
        EXPECT_EQ(fields[ix].attr.phys_mm.max, 1030, err_msg);
        EXPECT_EQ(fields[ix].attr.logc_mm.max, 13184, err_msg);
        // TODO(dgilhooley) Define Unit types in ulib/hid-parser.
        EXPECT_EQ(fields[ix].attr.unit.type, 0x11, err_msg);
        EXPECT_EQ(fields[ix].attr.unit.exp, -2, err_msg);
        EXPECT_EQ(fields[ix].attr.bit_sz, 16, err_msg);
        ++ix;

        // The Y Coordinate (most fields are inherited from X).
        EXPECT_EQ(fields[ix].type, hid::kInput);
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kGenericDesktop, err_msg);
        EXPECT_EQ(fields[ix].attr.usage.usage, hid::usage::GenericDesktop::kY, err_msg);
        EXPECT_EQ(fields[ix].attr.phys_mm.min, 0, err_msg);
        EXPECT_EQ(fields[ix].attr.phys_mm.max, 680, err_msg);
        EXPECT_EQ(fields[ix].attr.logc_mm.max, 8704, err_msg);
        // TODO(dgilhooley) Define Unit types in ulib/hid-parser
        EXPECT_EQ(fields[ix].attr.unit.type, 0x11, err_msg);
        EXPECT_EQ(fields[ix].attr.unit.exp, -2, err_msg);
        EXPECT_EQ(fields[ix].attr.bit_sz, 16, err_msg);
        ++ix;

        EXPECT_EQ(fields[ix].type, hid::kInput);
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kDigitizer, err_msg);
        EXPECT_EQ(fields[ix].attr.usage.usage, 0x48, err_msg);
        EXPECT_EQ(fields[ix].attr.logc_mm.max, 13184, err_msg);
        EXPECT_EQ(fields[ix].attr.bit_sz, 16);
        ++ix;

        EXPECT_EQ(fields[ix].type, hid::kInput);
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kDigitizer, err_msg);
        EXPECT_EQ(fields[ix].attr.usage.usage, 0x49, err_msg);
        EXPECT_EQ(fields[ix].attr.logc_mm.max, 8704, err_msg);
        EXPECT_EQ(fields[ix].attr.bit_sz, 16);
        ++ix;

        EXPECT_EQ(fields[ix].type, hid::kInput);
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kDigitizer, err_msg);
        EXPECT_EQ(fields[ix].attr.usage.usage, hid::usage::Digitizer::kTipPressure, err_msg);
        EXPECT_EQ(fields[ix].attr.logc_mm.max, 255, err_msg);
        EXPECT_EQ(fields[ix].attr.bit_sz, 8);
        ++ix;

        EXPECT_EQ(fields[ix].type, hid::kInput);
        EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kDigitizer, err_msg);
        EXPECT_EQ(fields[ix].attr.usage.usage, hid::usage::Digitizer::kAzimuth, err_msg);
        EXPECT_EQ(fields[ix].attr.logc_mm.max, 360, err_msg);
        EXPECT_EQ(fields[ix].attr.bit_sz, 16);
        ++ix;
    }

    // Make sure we checked each of the report fields.
    ASSERT_EQ(ix, dev->report[0].input_count);

    END_TEST;
}

BEGIN_TEST_CASE(hidparser_tests)
RUN_TEST(itemize_acer12_rpt1)
RUN_TEST(itemize_eve_tablet_rpt)
RUN_TEST(parse_boot_mouse)
RUN_TEST(parse_hp_mouse)
RUN_TEST(parse_adaf_trinket)
RUN_TEST(parse_ps3_controller)
RUN_TEST(parse_acer12_touch)
RUN_TEST(parse_eve_tablet)
RUN_TEST(parse_asus_touch)
RUN_TEST(parse_eve_touchpad_v2)
END_TEST_CASE(hidparser_tests)
