// Copyright 2017 The Chromium OS 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 "midis/device_tracker.h"

#include <memory>
#include <utility>

#include <base/bind.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <brillo/test_helpers.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "midis/tests/test_helper.h"

namespace midis {

namespace {

const char kFakeName1[] = "Sample MIDI Device - 1";
const char kFakeManufacturer1[] = "Foo";
const uint32_t kFakeSysNum1 = 2;
const uint32_t kFakeDevNum1 = 0;
const uint32_t kFakeSubdevs1 = 1;
const uint32_t kFakeFlags1 = 7;

const char kFakeName2[] = "Sample MIDI Device - 2";
const char kFakeManufacturer2[] = "Bar";
const uint32_t kFakeSysNum2 = 3;
const uint32_t kFakeDevNum2 = 1;
const uint32_t kFakeSubdevs2 = 2;
const uint32_t kFakeFlags2 = 6;

bool FakeInPortSubscribeCallback(uint32_t device_id, uint32_t port_id) {
  NOTIMPLEMENTED();
  return true;
}

int FakeOutPortSubscribeCallback(uint32_t device_id, uint32_t port_id) {
  NOTIMPLEMENTED();
  return 0;
}

void FakeInPortDeleteCallback(uint32_t device_id, uint32_t port_id) {
  NOTIMPLEMENTED();
}

void FakeOutPortDeleteCallback(int alsa_out_port_id) {
  NOTIMPLEMENTED();
}

void FakeSendMidiDataCallback(int alsa_out_port_id,
                              const uint8_t* buf,
                              size_t buf_len) {
  NOTIMPLEMENTED();
}

}  // namespace

class DeviceTrackerTest : public ::testing::Test {
 protected:
  DeviceTracker tracker_;
};

// Check whether a 2 devices get successfully added to the devices map.
TEST_F(DeviceTrackerTest, Add2DevicesPositive) {
  // Since this test isn't testing the Device class functionality, it's OK
  // to set the callbacks to be no-ops.
  auto dev = std::make_unique<Device>(kFakeName1,
                                      kFakeManufacturer1,
                                      kFakeSysNum1,
                                      kFakeDevNum1,
                                      kFakeSubdevs1,
                                      kFakeFlags1,
                                      base::Bind(&FakeInPortSubscribeCallback),
                                      base::Bind(&FakeOutPortSubscribeCallback),
                                      base::Bind(&FakeInPortDeleteCallback),
                                      base::Bind(&FakeOutPortDeleteCallback),
                                      base::Bind(&FakeSendMidiDataCallback),
                                      std::map<uint32_t, unsigned int>());
  tracker_.AddDevice(std::move(dev));

  auto dev2 =
      std::make_unique<Device>(kFakeName2,
                               kFakeManufacturer2,
                               kFakeSysNum2,
                               kFakeDevNum2,
                               kFakeSubdevs2,
                               kFakeFlags2,
                               base::Bind(&FakeInPortSubscribeCallback),
                               base::Bind(&FakeOutPortSubscribeCallback),
                               base::Bind(&FakeInPortDeleteCallback),
                               base::Bind(&FakeOutPortDeleteCallback),
                               base::Bind(&FakeSendMidiDataCallback),
                               std::map<uint32_t, unsigned int>());
  tracker_.AddDevice(std::move(dev2));

  EXPECT_EQ(2, tracker_.devices_.size());

  auto it = tracker_.devices_.begin();
  uint32_t device_id = it->first;
  Device const* device = it->second.get();
  EXPECT_THAT(device, DeviceMatcher(device_id, kFakeName1, kFakeManufacturer1));

  it++;
  device_id = it->first;
  device = it->second.get();
  EXPECT_THAT(device, DeviceMatcher(device_id, kFakeName2, kFakeManufacturer2));
}

// Check whether a device gets successfully added, then removed from the devices
// map.
TEST_F(DeviceTrackerTest, AddRemoveDevicePositive) {
  auto dev = std::make_unique<Device>(kFakeName1,
                                      kFakeManufacturer1,
                                      kFakeSysNum1,
                                      kFakeDevNum1,
                                      kFakeSubdevs1,
                                      kFakeFlags1,
                                      base::Bind(&FakeInPortSubscribeCallback),
                                      base::Bind(&FakeOutPortSubscribeCallback),
                                      base::Bind(&FakeInPortDeleteCallback),
                                      base::Bind(&FakeOutPortDeleteCallback),
                                      base::Bind(&FakeSendMidiDataCallback),
                                      std::map<uint32_t, unsigned int>());
  tracker_.AddDevice(std::move(dev));
  EXPECT_EQ(1, tracker_.devices_.size());

  tracker_.RemoveDevice(kFakeSysNum1, kFakeDevNum1);
  EXPECT_EQ(0, tracker_.devices_.size());
}

// Check whether a device gets successfully added, but not removed.
TEST_F(DeviceTrackerTest, AddDeviceRemoveNegative) {
  auto dev = std::make_unique<Device>(kFakeName1,
                                      kFakeManufacturer1,
                                      kFakeSysNum1,
                                      kFakeDevNum1,
                                      kFakeSubdevs1,
                                      kFakeFlags1,
                                      base::Bind(&FakeInPortSubscribeCallback),
                                      base::Bind(&FakeOutPortSubscribeCallback),
                                      base::Bind(&FakeInPortDeleteCallback),
                                      base::Bind(&FakeOutPortDeleteCallback),
                                      base::Bind(&FakeSendMidiDataCallback),
                                      std::map<uint32_t, unsigned int>());
  tracker_.AddDevice(std::move(dev));
  EXPECT_EQ(1, tracker_.devices_.size());

  tracker_.RemoveDevice(kFakeSysNum2, kFakeDevNum1);
  EXPECT_EQ(1, tracker_.devices_.size());
}

}  // namespace midis
