// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/midi/midi_manager_usb.h"

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <string>
#include <utility>

#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ptr_exclusion.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "media/midi/midi_service.h"
#include "media/midi/usb_midi_device.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace midi {

namespace {

using mojom::PortState;
using mojom::Result;

template<typename T, size_t N>
std::vector<T> ToVector(const T (&array)[N]) {
  return std::vector<T>(array, array + N);
}

class Logger {
 public:
  Logger() = default;

  Logger(const Logger&) = delete;
  Logger& operator=(const Logger&) = delete;

  ~Logger() = default;

  void AddLog(const std::string& message) { log_ += message; }
  std::string TakeLog() {
    std::string result;
    result.swap(log_);
    return result;
  }

 private:
  std::string log_;
};

class FakeUsbMidiDevice : public UsbMidiDevice {
 public:
  explicit FakeUsbMidiDevice(Logger* logger) : logger_(logger) {}

  FakeUsbMidiDevice(const FakeUsbMidiDevice&) = delete;
  FakeUsbMidiDevice& operator=(const FakeUsbMidiDevice&) = delete;

  ~FakeUsbMidiDevice() override = default;

  std::vector<uint8_t> GetDescriptors() override {
    logger_->AddLog("UsbMidiDevice::GetDescriptors\n");
    return descriptors_;
  }

  std::string GetManufacturer() override { return manufacturer_; }
  std::string GetProductName() override { return product_name_; }
  std::string GetDeviceVersion() override { return device_version_; }

  void Send(int endpoint_number, const std::vector<uint8_t>& data) override {
    logger_->AddLog("UsbMidiDevice::Send ");
    logger_->AddLog(base::StringPrintf("endpoint = %d data =",
                                       endpoint_number));
    for (size_t i = 0; i < data.size(); ++i)
      logger_->AddLog(base::StringPrintf(" 0x%02x", data[i]));
    logger_->AddLog("\n");
  }

  void SetDescriptors(const std::vector<uint8_t> descriptors) {
    descriptors_ = descriptors;
  }
  void SetManufacturer(const std::string& manufacturer) {
    manufacturer_ = manufacturer;
  }
  void SetProductName(const std::string& product_name) {
    product_name_ = product_name;
  }
  void SetDeviceVersion(const std::string& device_version) {
    device_version_ = device_version;
  }

 private:
  std::vector<uint8_t> descriptors_;
  std::string manufacturer_;
  std::string product_name_;
  std::string device_version_;
  raw_ptr<Logger> logger_;
};

class FakeMidiManagerClient : public MidiManagerClient {
 public:
  explicit FakeMidiManagerClient(Logger* logger)
      : complete_start_session_(false),
        result_(Result::NOT_SUPPORTED),
        logger_(logger) {}

  FakeMidiManagerClient(const FakeMidiManagerClient&) = delete;
  FakeMidiManagerClient& operator=(const FakeMidiManagerClient&) = delete;

  ~FakeMidiManagerClient() override = default;

  void AddInputPort(const mojom::PortInfo& info) override {
    input_ports_.push_back(info);
  }

  void AddOutputPort(const mojom::PortInfo& info) override {
    output_ports_.push_back(info);
  }

  void SetInputPortState(uint32_t port_index, PortState state) override {}

  void SetOutputPortState(uint32_t port_index, PortState state) override {}

  void CompleteStartSession(Result result) override {
    complete_start_session_ = true;
    result_ = result;
  }

  void ReceiveMidiData(uint32_t port_index,
                       const uint8_t* data,
                       size_t size,
                       base::TimeTicks timestamp) override {
    logger_->AddLog("MidiManagerClient::ReceiveMidiData ");
    logger_->AddLog(
        base::StringPrintf("usb:port_index = %d data =", port_index));
    for (size_t i = 0; i < size; ++i)
      logger_->AddLog(base::StringPrintf(" 0x%02x", data[i]));
    logger_->AddLog("\n");
  }

  void AccumulateMidiBytesSent(size_t size) override {
    logger_->AddLog("MidiManagerClient::AccumulateMidiBytesSent ");
    // Windows has no "%zu".
    logger_->AddLog(base::StringPrintf("size = %u\n",
                                       static_cast<unsigned>(size)));
  }

  void Detach() override {}

  bool complete_start_session_;
  Result result_;
  std::vector<mojom::PortInfo> input_ports_;
  std::vector<mojom::PortInfo> output_ports_;

 private:
  raw_ptr<Logger> logger_;
};

class TestUsbMidiDeviceFactory : public UsbMidiDevice::Factory {
 public:
  TestUsbMidiDeviceFactory() = default;

  TestUsbMidiDeviceFactory(const TestUsbMidiDeviceFactory&) = delete;
  TestUsbMidiDeviceFactory& operator=(const TestUsbMidiDeviceFactory&) = delete;

  ~TestUsbMidiDeviceFactory() override = default;
  void EnumerateDevices(UsbMidiDeviceDelegate* device,
                        Callback callback) override {
    callback_ = std::move(callback);
  }

  Callback callback_;
};

class MidiManagerUsbForTesting : public MidiManagerUsb {
 public:
  MidiManagerUsbForTesting(
      std::unique_ptr<UsbMidiDevice::Factory> device_factory,
      MidiService* service)
      : MidiManagerUsb(service, std::move(device_factory)) {}

  MidiManagerUsbForTesting(const MidiManagerUsbForTesting&) = delete;
  MidiManagerUsbForTesting& operator=(const MidiManagerUsbForTesting&) = delete;

  ~MidiManagerUsbForTesting() override = default;

  void CallCompleteInitialization(Result result) {
    CompleteInitialization(result);
    base::RunLoop run_loop;
    run_loop.RunUntilIdle();
  }
};

class MidiManagerFactoryForTesting : public midi::MidiService::ManagerFactory {
 public:
  MidiManagerFactoryForTesting() = default;
  ~MidiManagerFactoryForTesting() override = default;
  std::unique_ptr<midi::MidiManager> Create(
      midi::MidiService* service) override {
    std::unique_ptr<TestUsbMidiDeviceFactory> device_factory =
        std::make_unique<TestUsbMidiDeviceFactory>();
    device_factory_ = device_factory.get();
    std::unique_ptr<MidiManagerUsbForTesting> manager =
        std::make_unique<MidiManagerUsbForTesting>(std::move(device_factory),
                                                   service);
    // |manager| will be owned by the caller MidiService instance, and valid
    // while the MidiService instance is running.
    // MidiService::Shutdown() or destructor will destruct it, and |manager_|
    // get to be invalid after that.
    manager_ = manager.get();
    return manager;
  }
  MidiManagerUsb* manager() {
    DCHECK(manager_);
    return manager_;
  }
  TestUsbMidiDeviceFactory* device_factory() {
    DCHECK(device_factory_);
    return device_factory_;
  }

 private:
  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
  // #constexpr-ctor-field-initializer
  RAW_PTR_EXCLUSION TestUsbMidiDeviceFactory* device_factory_ = nullptr;
  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
  // #constexpr-ctor-field-initializer
  RAW_PTR_EXCLUSION MidiManagerUsbForTesting* manager_ = nullptr;
};

class MidiManagerUsbTest : public ::testing::Test {
 public:
  MidiManagerUsbTest() {
    std::unique_ptr<MidiManagerFactoryForTesting> factory =
        std::make_unique<MidiManagerFactoryForTesting>();
    factory_ = factory.get();
    service_ = std::make_unique<MidiService>(std::move(factory));
  }

  MidiManagerUsbTest(const MidiManagerUsbTest&) = delete;
  MidiManagerUsbTest& operator=(const MidiManagerUsbTest&) = delete;

  ~MidiManagerUsbTest() override {
    service_->Shutdown();
    base::RunLoop run_loop;
    run_loop.RunUntilIdle();

    std::string leftover_logs = logger_.TakeLog();
    if (!leftover_logs.empty()) {
      ADD_FAILURE() << "Log should be empty: " << leftover_logs;
    }
  }

 protected:
  void Initialize() {
    client_ = std::make_unique<FakeMidiManagerClient>(&logger_);
    service_->StartSession(client_.get());
  }

  void Finalize() { service_->EndSession(client_.get()); }

  bool IsInitializationCallbackInvoked() {
    return client_->complete_start_session_;
  }

  Result GetInitializationResult() { return client_->result_; }

  void RunCallbackUntilCallbackInvoked(
      bool result, UsbMidiDevice::Devices* devices) {
    std::move(factory_->device_factory()->callback_).Run(result, devices);
    while (!client_->complete_start_session_) {
      base::RunLoop run_loop;
      run_loop.RunUntilIdle();
    }
  }

  const std::vector<mojom::PortInfo>& input_ports() {
    return client_->input_ports_;
  }
  const std::vector<mojom::PortInfo>& output_ports() {
    return client_->output_ports_;
  }

  MidiManagerUsb* manager() { return factory_->manager(); }

  std::unique_ptr<FakeMidiManagerClient> client_;
  Logger logger_;

 private:
  std::unique_ptr<MidiService> service_;  // Must outlive `factory_`.
  raw_ptr<MidiManagerFactoryForTesting> factory_;
  base::test::SingleThreadTaskEnvironment task_environment_;
};


TEST_F(MidiManagerUsbTest, Initialize) {
  std::unique_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
  uint8_t descriptors[] = {
      0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
      0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
      0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
      0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
      0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
      0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
      0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
      0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
      0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
      0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
      0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
      0x01, 0x01, 0x07,
  };
  device->SetDescriptors(ToVector(descriptors));
  device->SetManufacturer("vendor1");
  device->SetProductName("device1");
  device->SetDeviceVersion("1.02");

  Initialize();
  UsbMidiDevice::Devices devices;
  devices.push_back(std::move(device));
  EXPECT_FALSE(IsInitializationCallbackInvoked());
  RunCallbackUntilCallbackInvoked(true, &devices);
  EXPECT_EQ(Result::OK, GetInitializationResult());

  ASSERT_EQ(1u, input_ports().size());
  EXPECT_EQ("usb:port-0-2", input_ports()[0].id);
  EXPECT_EQ("vendor1", input_ports()[0].manufacturer);
  EXPECT_EQ("device1", input_ports()[0].name);
  EXPECT_EQ("1.02", input_ports()[0].version);

  ASSERT_EQ(2u, output_ports().size());
  EXPECT_EQ("usb:port-0-0", output_ports()[0].id);
  EXPECT_EQ("vendor1", output_ports()[0].manufacturer);
  EXPECT_EQ("device1", output_ports()[0].name);
  EXPECT_EQ("1.02", output_ports()[0].version);
  EXPECT_EQ("usb:port-0-1", output_ports()[1].id);
  EXPECT_EQ("vendor1", output_ports()[1].manufacturer);
  EXPECT_EQ("device1", output_ports()[1].name);
  EXPECT_EQ("1.02", output_ports()[1].version);

  ASSERT_TRUE(manager()->input_stream());
  std::vector<UsbMidiJack> jacks = manager()->input_stream()->jacks();
  ASSERT_EQ(2u, manager()->output_streams().size());
  EXPECT_EQ(2u, manager()->output_streams()[0]->jack().jack_id);
  EXPECT_EQ(3u, manager()->output_streams()[1]->jack().jack_id);
  ASSERT_EQ(1u, jacks.size());
  EXPECT_EQ(2, jacks[0].endpoint_number());

  EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_.TakeLog());
}

TEST_F(MidiManagerUsbTest, InitializeMultipleDevices) {
  std::unique_ptr<FakeUsbMidiDevice> device1(new FakeUsbMidiDevice(&logger_));
  std::unique_ptr<FakeUsbMidiDevice> device2(new FakeUsbMidiDevice(&logger_));
  uint8_t descriptors[] = {
      0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
      0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
      0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
      0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
      0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
      0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
      0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
      0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
      0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
      0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
      0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
      0x01, 0x01, 0x07,
  };
  device1->SetDescriptors(ToVector(descriptors));
  device1->SetManufacturer("vendor1");
  device1->SetProductName("device1");
  device1->SetDeviceVersion("1.02");
  device2->SetDescriptors(ToVector(descriptors));
  device2->SetManufacturer("vendor2");
  device2->SetProductName("device2");
  device2->SetDeviceVersion("98.76");

  Initialize();
  UsbMidiDevice::Devices devices;
  devices.push_back(std::move(device1));
  devices.push_back(std::move(device2));
  EXPECT_FALSE(IsInitializationCallbackInvoked());
  RunCallbackUntilCallbackInvoked(true, &devices);
  EXPECT_EQ(Result::OK, GetInitializationResult());

  ASSERT_EQ(2u, input_ports().size());
  EXPECT_EQ("usb:port-0-2", input_ports()[0].id);
  EXPECT_EQ("vendor1", input_ports()[0].manufacturer);
  EXPECT_EQ("device1", input_ports()[0].name);
  EXPECT_EQ("1.02", input_ports()[0].version);
  EXPECT_EQ("usb:port-1-2", input_ports()[1].id);
  EXPECT_EQ("vendor2", input_ports()[1].manufacturer);
  EXPECT_EQ("device2", input_ports()[1].name);
  EXPECT_EQ("98.76", input_ports()[1].version);

  ASSERT_EQ(4u, output_ports().size());
  EXPECT_EQ("usb:port-0-0", output_ports()[0].id);
  EXPECT_EQ("vendor1", output_ports()[0].manufacturer);
  EXPECT_EQ("device1", output_ports()[0].name);
  EXPECT_EQ("1.02", output_ports()[0].version);
  EXPECT_EQ("usb:port-0-1", output_ports()[1].id);
  EXPECT_EQ("vendor1", output_ports()[1].manufacturer);
  EXPECT_EQ("device1", output_ports()[1].name);
  EXPECT_EQ("1.02", output_ports()[1].version);
  EXPECT_EQ("usb:port-1-0", output_ports()[2].id);
  EXPECT_EQ("vendor2", output_ports()[2].manufacturer);
  EXPECT_EQ("device2", output_ports()[2].name);
  EXPECT_EQ("98.76", output_ports()[2].version);
  EXPECT_EQ("usb:port-1-1", output_ports()[3].id);
  EXPECT_EQ("vendor2", output_ports()[3].manufacturer);
  EXPECT_EQ("device2", output_ports()[3].name);
  EXPECT_EQ("98.76", output_ports()[3].version);

  ASSERT_TRUE(manager()->input_stream());
  std::vector<UsbMidiJack> jacks = manager()->input_stream()->jacks();
  ASSERT_EQ(4u, manager()->output_streams().size());
  EXPECT_EQ(2u, manager()->output_streams()[0]->jack().jack_id);
  EXPECT_EQ(3u, manager()->output_streams()[1]->jack().jack_id);
  ASSERT_EQ(2u, jacks.size());
  EXPECT_EQ(2, jacks[0].endpoint_number());

  EXPECT_EQ(
      "UsbMidiDevice::GetDescriptors\n"
      "UsbMidiDevice::GetDescriptors\n",
      logger_.TakeLog());
}

TEST_F(MidiManagerUsbTest, InitializeFail) {
  Initialize();

  EXPECT_FALSE(IsInitializationCallbackInvoked());
  RunCallbackUntilCallbackInvoked(false, NULL);
  EXPECT_EQ(Result::INITIALIZATION_ERROR, GetInitializationResult());
}

TEST_F(MidiManagerUsbTest, InitializeFailBecauseOfInvalidDescriptors) {
  std::unique_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
  uint8_t descriptors[] = {0x04};
  device->SetDescriptors(ToVector(descriptors));

  Initialize();
  UsbMidiDevice::Devices devices;
  devices.push_back(std::move(device));
  EXPECT_FALSE(IsInitializationCallbackInvoked());
  RunCallbackUntilCallbackInvoked(true, &devices);
  EXPECT_EQ(Result::INITIALIZATION_ERROR, GetInitializationResult());
  EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_.TakeLog());
}

TEST_F(MidiManagerUsbTest, Send) {
  Initialize();
  std::unique_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
  uint8_t descriptors[] = {
      0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
      0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
      0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
      0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
      0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
      0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
      0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
      0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
      0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
      0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
      0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
      0x01, 0x01, 0x07,
  };

  device->SetDescriptors(ToVector(descriptors));
  uint8_t data[] = {
      0x90, 0x45, 0x7f, 0xf0, 0x00, 0x01, 0xf7,
  };

  UsbMidiDevice::Devices devices;
  devices.push_back(std::move(device));
  EXPECT_FALSE(IsInitializationCallbackInvoked());
  RunCallbackUntilCallbackInvoked(true, &devices);
  EXPECT_EQ(Result::OK, GetInitializationResult());
  ASSERT_EQ(2u, manager()->output_streams().size());

  manager()->DispatchSendMidiData(client_.get(), 1, ToVector(data),
                                  base::TimeTicks());
  // Since UsbMidiDevice::Send is posted as a task, RunLoop should run to
  // invoke the task.
  base::RunLoop run_loop;
  run_loop.RunUntilIdle();
  EXPECT_EQ("UsbMidiDevice::GetDescriptors\n"
            "UsbMidiDevice::Send endpoint = 2 data = "
            "0x19 0x90 0x45 0x7f "
            "0x14 0xf0 0x00 0x01 "
            "0x15 0xf7 0x00 0x00\n"
            "MidiManagerClient::AccumulateMidiBytesSent size = 7\n",
            logger_.TakeLog());
}

TEST_F(MidiManagerUsbTest, SendFromCompromizedRenderer) {
  std::unique_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
  uint8_t descriptors[] = {
      0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
      0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
      0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
      0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
      0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
      0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
      0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
      0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
      0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
      0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
      0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
      0x01, 0x01, 0x07,
  };

  device->SetDescriptors(ToVector(descriptors));
  uint8_t data[] = {
      0x90, 0x45, 0x7f, 0xf0, 0x00, 0x01, 0xf7,
  };

  Initialize();
  UsbMidiDevice::Devices devices;
  devices.push_back(std::move(device));
  EXPECT_FALSE(IsInitializationCallbackInvoked());
  RunCallbackUntilCallbackInvoked(true, &devices);
  EXPECT_EQ(Result::OK, GetInitializationResult());
  ASSERT_EQ(2u, manager()->output_streams().size());
  EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_.TakeLog());

  // The specified port index is invalid. The manager must ignore the request.
  manager()->DispatchSendMidiData(client_.get(), 99, ToVector(data),
                                  base::TimeTicks());
  EXPECT_EQ("", logger_.TakeLog());

  // The specified port index is invalid. The manager must ignore the request.
  manager()->DispatchSendMidiData(client_.get(), 2, ToVector(data),
                                  base::TimeTicks());
  EXPECT_EQ("", logger_.TakeLog());
}

TEST_F(MidiManagerUsbTest, Receive) {
  std::unique_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
  uint8_t descriptors[] = {
      0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
      0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
      0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
      0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
      0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
      0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
      0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
      0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
      0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
      0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
      0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
      0x01, 0x01, 0x07,
  };

  device->SetDescriptors(ToVector(descriptors));
  uint8_t data[] = {
      0x09, 0x90, 0x45, 0x7f, 0x04, 0xf0, 0x00,
      0x01, 0x49, 0x90, 0x88, 0x99,  // This data should be ignored (CN = 4).
      0x05, 0xf7, 0x00, 0x00,
  };

  Initialize();
  UsbMidiDevice::Devices devices;
  UsbMidiDevice* device_raw = device.get();
  devices.push_back(std::move(device));
  EXPECT_FALSE(IsInitializationCallbackInvoked());
  RunCallbackUntilCallbackInvoked(true, &devices);
  EXPECT_EQ(Result::OK, GetInitializationResult());

  manager()->ReceiveUsbMidiData(device_raw, 2, data, std::size(data),
                                base::TimeTicks());
  Finalize();

  EXPECT_EQ(
      "UsbMidiDevice::GetDescriptors\n"
      "MidiManagerClient::ReceiveMidiData usb:port_index = 0 "
      "data = 0x90 0x45 0x7f\n"
      "MidiManagerClient::ReceiveMidiData usb:port_index = 0 "
      "data = 0xf0 0x00 0x01\n"
      "MidiManagerClient::ReceiveMidiData usb:port_index = 0 data = 0xf7\n",
      logger_.TakeLog());
}

TEST_F(MidiManagerUsbTest, AttachDevice) {
  uint8_t descriptors[] = {
      0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
      0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
      0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
      0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
      0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
      0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
      0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
      0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
      0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
      0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
      0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
      0x01, 0x01, 0x07,
  };

  Initialize();
  UsbMidiDevice::Devices devices;
  EXPECT_FALSE(IsInitializationCallbackInvoked());
  RunCallbackUntilCallbackInvoked(true, &devices);
  EXPECT_EQ(Result::OK, GetInitializationResult());

  ASSERT_EQ(0u, input_ports().size());
  ASSERT_EQ(0u, output_ports().size());
  ASSERT_TRUE(manager()->input_stream());
  std::vector<UsbMidiJack> jacks = manager()->input_stream()->jacks();
  ASSERT_EQ(0u, manager()->output_streams().size());
  ASSERT_EQ(0u, jacks.size());
  EXPECT_EQ("", logger_.TakeLog());

  std::unique_ptr<FakeUsbMidiDevice> new_device(
      new FakeUsbMidiDevice(&logger_));
  new_device->SetDescriptors(ToVector(descriptors));
  manager()->OnDeviceAttached(std::move(new_device));

  ASSERT_EQ(1u, input_ports().size());
  ASSERT_EQ(2u, output_ports().size());
  ASSERT_TRUE(manager()->input_stream());
  jacks = manager()->input_stream()->jacks();
  ASSERT_EQ(2u, manager()->output_streams().size());
  EXPECT_EQ(2u, manager()->output_streams()[0]->jack().jack_id);
  EXPECT_EQ(3u, manager()->output_streams()[1]->jack().jack_id);
  ASSERT_EQ(1u, jacks.size());
  EXPECT_EQ(2, jacks[0].endpoint_number());
  EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_.TakeLog());
}

}  // namespace

}  // namespace midi
