// Copyright 2019 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 <usb/usb.h>

#include <unittest/unittest.h>

namespace {

// Raw descriptors obtained from a Pixelbook with a USB flash drive connected to it.
// To re-generate this, merge the tool at commit
// b934c6e31e31a291b3761383b28cd1d0004e5423 on sandbox/idwmaster/ums-descriptor-debugger
// Be careful to not accidentally submit this tool in a CL
// (it is meant for debugging, not production use).
// to run the tool; simply type the command: debug
// in your device's terminal after connecting a USB mass storage device.
// The raw descriptor dump will be put in /data/debug
// You can copy this to your PC with fx cp
// and convert to an unsigned char array with your favorite conversion script.
constexpr unsigned char kDescriptors[] = {
    // Data from a real USB flash drive
    9, 4, 0, 0, 2, 8, 6, 80, 0, 7, 5, 129, 2,
    0, 4, 0, 6, 48, 3, 0, 0, 0, 7, 5, 2, 2, 0,
    4, 0, 6, 48, 3, 0, 0, 0,
    // Synthetic data to test alternate interfaces
    9, 4, 0, 1, 2, 8, 6, 80, 0};

constexpr usb_interface_descriptor_t kParsedDescriptors[] = {
    // Data from a real USB flash drive
    {9, 4, 0, 0, 2, 8, 6, 80, 0},
    // Synthetic data to test alternate interfaces
    {9, 4, 0, 1, 2, 8, 6, 80, 0}};

const usb_endpoint_descriptor_t kEndpointDescriptors[] = {
    {7, 5, 129, 2, 1024, 0},
    {7, 5, 2, 2, 1024, 0}};

static void GetDescriptors(
    void* ctx,
    void* out_descs_buffer,
    size_t descs_size,
    size_t* out_descs_actual) {
    if (descs_size != sizeof(kDescriptors)) {
        return;
    }
    memcpy(out_descs_buffer, kDescriptors, descs_size);
    *out_descs_actual = descs_size;
}

static size_t GetDescriptorsLength(void* context) {
    return sizeof(kDescriptors);
}

bool InterfaceListTest() {
    BEGIN_TEST;
    usb_protocol_ops_t ops;
    ops.get_descriptors_length = GetDescriptorsLength;
    ops.get_descriptors = GetDescriptors;
    usb_protocol_t proto = {};
    proto.ops = &ops;
    usb::InterfaceList list(&proto, true);
    ASSERT_EQ(ZX_OK, list.check(), "");
    size_t count = 0;
    for (auto interface : list) {
        ASSERT_EQ(
            0,
            memcmp(kParsedDescriptors + count, interface.descriptor(),
                   sizeof(usb_interface_descriptor_t)),
            "");
        size_t endpoint_count = 0;
        for (auto endpoint : interface) {
            ASSERT_EQ(
                0,
                memcmp(kEndpointDescriptors + endpoint_count, &endpoint,
                       sizeof(usb_endpoint_descriptor_t)),
                "");
            endpoint_count++;
        }
        ASSERT_EQ(2, endpoint_count, "");
        count++;
    }
    ASSERT_EQ(count, 1, "");
    count = 0;
    usb::InterfaceList list2(&proto);
    for (auto interface : list2) {
        ASSERT_EQ(0,
                  memcmp(kParsedDescriptors + count, interface.descriptor(),
                         sizeof(usb_interface_descriptor_t)),
                  "");
        size_t endpoint_count = 0;
        for (auto endpoint : interface) {
            ASSERT_EQ(0,
                      memcmp(kEndpointDescriptors + endpoint_count,
                             &endpoint,
                             sizeof(usb_endpoint_descriptor_t)),
                      "");
            endpoint_count++;
        }
        ASSERT_EQ(count ? 0U : 2U, endpoint_count, "");
        count++;
    }
    ASSERT_EQ(count, 2, "");
    count = 0;
    for (auto iter = list2.cbegin(); iter != list2.cend(); iter++) {
        auto interface = *iter;
        ASSERT_EQ(0, memcmp(kParsedDescriptors + count, interface.descriptor(), sizeof(usb_interface_descriptor_t)),
                  "");
        size_t endpoint_count = 0;
        for (auto endpoint : interface) {
            ASSERT_EQ(0,
                      memcmp(kEndpointDescriptors + endpoint_count, &endpoint,
                             sizeof(usb_endpoint_descriptor_t)),
                      "");
            endpoint_count++;
        }
        ASSERT_EQ(count ? 0U : 2U, endpoint_count, "");
        count++;
    }
    END_TEST;
}
} // namespace

BEGIN_TEST_CASE(usb_wrapper_tests)
RUN_NAMED_TEST("InterfaceList test", InterfaceListTest)
END_TEST_CASE(usb_wrapper_tests)
