// 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, 0);
    EXPECT_EQ(fields[4].attr.phys_mm.max, 0);
    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, 0);
    EXPECT_EQ(fields[5].attr.phys_mm.max, 0);
    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, 0);
    EXPECT_EQ(fields[8].attr.phys_mm.max, 0);
    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, 0);
    EXPECT_EQ(fields[9].attr.phys_mm.max, 0);
    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, 0);
    EXPECT_EQ(fields[10].attr.phys_mm.max, 0);
    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)
