// Copyright 2015 The Chromium 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 <set>
#include <string>

#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/thread_task_runner_handle.h"
#include "device/core/device_client.h"
#include "device/devices_app/usb/device_impl.h"
#include "device/devices_app/usb/device_manager_impl.h"
#include "device/usb/mock_usb_device.h"
#include "device/usb/mock_usb_device_handle.h"
#include "device/usb/mock_usb_service.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"

using ::testing::Invoke;
using ::testing::_;

namespace device {
namespace usb {

namespace {

class TestPermissionProvider : public PermissionProvider {
 public:
  TestPermissionProvider(mojo::InterfaceRequest<PermissionProvider> request)
      : binding_(this, request.Pass()) {}
  ~TestPermissionProvider() override {}

  void HasDevicePermission(
      mojo::Array<mojo::String> requested_guids,
      const HasDevicePermissionCallback& callback) override {
    // Permission to access all devices granted.
    callback.Run(requested_guids.Pass());
  }

 private:
  mojo::StrongBinding<PermissionProvider> binding_;
};

class TestDeviceClient : public DeviceClient {
 public:
  TestDeviceClient() {}
  ~TestDeviceClient() override {}

  MockUsbService& mock_usb_service() { return mock_usb_service_; }

 private:
  // DeviceClient implementation:
  UsbService* GetUsbService() override { return &mock_usb_service_; }

  MockUsbService mock_usb_service_;
};

class USBDeviceManagerImplTest : public testing::Test {
 public:
  USBDeviceManagerImplTest()
      : device_client_(new TestDeviceClient),
        message_loop_(new base::MessageLoop) {}
  ~USBDeviceManagerImplTest() override {}

 protected:
  MockUsbService& mock_usb_service() {
    return device_client_->mock_usb_service();
  }

  DeviceManagerPtr ConnectToDeviceManager() {
    PermissionProviderPtr permission_provider;
    new TestPermissionProvider(mojo::GetProxy(&permission_provider));
    DeviceManagerPtr device_manager;
    new DeviceManagerImpl(mojo::GetProxy(&device_manager),
                          permission_provider.Pass(),
                          base::ThreadTaskRunnerHandle::Get());
    return device_manager.Pass();
  }

 private:
  scoped_ptr<TestDeviceClient> device_client_;
  scoped_ptr<base::MessageLoop> message_loop_;
};

class MockOpenCallback {
 public:
  explicit MockOpenCallback(UsbDevice* device) : device_(device) {}

  void Open(const UsbDevice::OpenCallback& callback) {
    device_handle_ = new MockUsbDeviceHandle(device_);
    callback.Run(device_handle_);
  }

  scoped_refptr<MockUsbDeviceHandle> mock_handle() { return device_handle_; }

 private:
  UsbDevice* device_;
  scoped_refptr<MockUsbDeviceHandle> device_handle_;
};

void ExpectDevicesAndThen(const std::set<std::string>& expected_guids,
                          const base::Closure& continuation,
                          mojo::Array<DeviceInfoPtr> results) {
  EXPECT_EQ(expected_guids.size(), results.size());
  std::set<std::string> actual_guids;
  for (size_t i = 0; i < results.size(); ++i)
    actual_guids.insert(results[i]->guid);
  EXPECT_EQ(expected_guids, actual_guids);
  continuation.Run();
}

void ExpectDeviceChangesAndThen(
    const std::set<std::string>& expected_added_guids,
    const std::set<std::string>& expected_removed_guids,
    const base::Closure& continuation,
    DeviceChangeNotificationPtr results) {
  EXPECT_EQ(expected_added_guids.size(), results->devices_added.size());
  std::set<std::string> actual_added_guids;
  for (size_t i = 0; i < results->devices_added.size(); ++i)
    actual_added_guids.insert(results->devices_added[i]->guid);
  EXPECT_EQ(expected_added_guids, actual_added_guids);
  EXPECT_EQ(expected_removed_guids.size(), results->devices_removed.size());
  std::set<std::string> actual_removed_guids;
  for (size_t i = 0; i < results->devices_removed.size(); ++i)
    actual_removed_guids.insert(results->devices_removed[i]);
  EXPECT_EQ(expected_removed_guids, actual_removed_guids);
  continuation.Run();
}

void ExpectDeviceInfoAndThen(const std::string& expected_guid,
                             const base::Closure& continuation,
                             DeviceInfoPtr device_info) {
  EXPECT_EQ(expected_guid, device_info->guid);
  continuation.Run();
}

void ExpectOpenDeviceError(OpenDeviceError expected_error,
                           OpenDeviceError actual_error) {
  EXPECT_EQ(expected_error, actual_error);
}

void FailOnGetDeviceInfoResponse(DeviceInfoPtr device_info) {
  FAIL();
}

}  // namespace

// Test basic GetDevices functionality to ensure that all mock devices are
// returned by the service.
TEST_F(USBDeviceManagerImplTest, GetDevices) {
  scoped_refptr<MockUsbDevice> device0 =
      new MockUsbDevice(0x1234, 0x5678, "ACME", "Frobinator", "ABCDEF");
  scoped_refptr<MockUsbDevice> device1 =
      new MockUsbDevice(0x1234, 0x5679, "ACME", "Frobinator+", "GHIJKL");
  scoped_refptr<MockUsbDevice> device2 =
      new MockUsbDevice(0x1234, 0x567a, "ACME", "Frobinator Mk II", "MNOPQR");

  mock_usb_service().AddDevice(device0);
  mock_usb_service().AddDevice(device1);
  mock_usb_service().AddDevice(device2);

  DeviceManagerPtr device_manager = ConnectToDeviceManager();

  EnumerationOptionsPtr options = EnumerationOptions::New();
  options->filters = mojo::Array<DeviceFilterPtr>::New(1);
  options->filters[0] = DeviceFilter::New();
  options->filters[0]->has_vendor_id = true;
  options->filters[0]->vendor_id = 0x1234;

  std::set<std::string> guids;
  guids.insert(device0->guid());
  guids.insert(device1->guid());
  guids.insert(device2->guid());

  base::RunLoop loop;
  device_manager->GetDevices(
      options.Pass(),
      base::Bind(&ExpectDevicesAndThen, guids, loop.QuitClosure()));
  loop.Run();
}

// Test requesting a single Device by GUID.
TEST_F(USBDeviceManagerImplTest, OpenDevice) {
  scoped_refptr<MockUsbDevice> mock_device =
      new MockUsbDevice(0x1234, 0x5678, "ACME", "Frobinator", "ABCDEF");

  mock_usb_service().AddDevice(mock_device);

  DeviceManagerPtr device_manager = ConnectToDeviceManager();

  // Should be called on the mock as a result of OpenDevice() below.
  EXPECT_CALL(*mock_device.get(), Open(_));

  MockOpenCallback open_callback(mock_device.get());
  ON_CALL(*mock_device.get(), Open(_))
      .WillByDefault(Invoke(&open_callback, &MockOpenCallback::Open));

  {
    base::RunLoop loop;
    DevicePtr device;
    device_manager->OpenDevice(
        mock_device->guid(), mojo::GetProxy(&device),
        base::Bind(&ExpectOpenDeviceError, OPEN_DEVICE_ERROR_OK));
    device->GetDeviceInfo(base::Bind(&ExpectDeviceInfoAndThen,
                                     mock_device->guid(), loop.QuitClosure()));
    loop.Run();
  }

  // The device should eventually be closed when its MessagePipe is closed.
  DCHECK(open_callback.mock_handle());
  EXPECT_CALL(*open_callback.mock_handle().get(), Close());

  DevicePtr bad_device;
  device_manager->OpenDevice(
      "not a real guid", mojo::GetProxy(&bad_device),
      base::Bind(&ExpectOpenDeviceError, OPEN_DEVICE_ERROR_NOT_FOUND));

  {
    base::RunLoop loop;
    bad_device.set_connection_error_handler(loop.QuitClosure());
    bad_device->GetDeviceInfo(base::Bind(&FailOnGetDeviceInfoResponse));
    loop.Run();
  }
}

// Test requesting device enumeration updates with GetDeviceChanges.
TEST_F(USBDeviceManagerImplTest, GetDeviceChanges) {
  scoped_refptr<MockUsbDevice> device0 =
      new MockUsbDevice(0x1234, 0x5678, "ACME", "Frobinator", "ABCDEF");
  scoped_refptr<MockUsbDevice> device1 =
      new MockUsbDevice(0x1234, 0x5679, "ACME", "Frobinator+", "GHIJKL");
  scoped_refptr<MockUsbDevice> device2 =
      new MockUsbDevice(0x1234, 0x567a, "ACME", "Frobinator Mk II", "MNOPQR");
  scoped_refptr<MockUsbDevice> device3 =
      new MockUsbDevice(0x1234, 0x567b, "ACME", "Frobinator Xtreme", "STUVWX");

  mock_usb_service().AddDevice(device0);

  DeviceManagerPtr device_manager = ConnectToDeviceManager();

  {
    // Call GetDevices once to make sure the device manager is up and running
    // or else we could end up waiting forever for device changes as the next
    // block races with the ServiceThreadHelper startup.
    std::set<std::string> guids;
    guids.insert(device0->guid());
    base::RunLoop loop;
    device_manager->GetDevices(
        nullptr, base::Bind(&ExpectDevicesAndThen, guids, loop.QuitClosure()));
    loop.Run();
  }

  mock_usb_service().AddDevice(device1);
  mock_usb_service().AddDevice(device2);
  mock_usb_service().RemoveDevice(device1);

  {
    std::set<std::string> added_guids;
    std::set<std::string> removed_guids;
    added_guids.insert(device2->guid());
    base::RunLoop loop;
    device_manager->GetDeviceChanges(base::Bind(&ExpectDeviceChangesAndThen,
                                                added_guids, removed_guids,
                                                loop.QuitClosure()));
    loop.Run();
  }

  mock_usb_service().RemoveDevice(device0);
  mock_usb_service().RemoveDevice(device2);
  mock_usb_service().AddDevice(device3);

  {
    std::set<std::string> added_guids;
    std::set<std::string> removed_guids;
    added_guids.insert(device3->guid());
    removed_guids.insert(device0->guid());
    removed_guids.insert(device2->guid());
    base::RunLoop loop;
    device_manager->GetDeviceChanges(base::Bind(&ExpectDeviceChangesAndThen,
                                                added_guids, removed_guids,
                                                loop.QuitClosure()));
    loop.Run();
  }
}

}  // namespace usb
}  // namespace device
