// Copyright 2018 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 "chromecast/device/bluetooth/le/gatt_client_manager_impl.h"

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/test/mock_callback.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chromecast/device/bluetooth/bluetooth_util.h"
#include "chromecast/device/bluetooth/le/remote_characteristic.h"
#include "chromecast/device/bluetooth/le/remote_descriptor.h"
#include "chromecast/device/bluetooth/le/remote_device_impl.h"
#include "chromecast/device/bluetooth/le/remote_service.h"
#include "chromecast/device/bluetooth/shlib/mock_gatt_client.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::Return;

namespace chromecast {
namespace bluetooth {


namespace {

const bluetooth_v2_shlib::Addr kTestAddr1 = {
    {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}};
const bluetooth_v2_shlib::Addr kTestAddr2 = {
    {0x10, 0x11, 0x12, 0x13, 0x14, 0x15}};
const bluetooth_v2_shlib::Addr kTestAddr3 = {
    {0x20, 0x21, 0x22, 0x23, 0x24, 0x25}};
const bluetooth_v2_shlib::Addr kTestAddr4 = {
    {0x30, 0x31, 0x32, 0x33, 0x34, 0x35}};

class MockGattClientManagerObserver : public GattClientManager::Observer {
 public:
  MOCK_METHOD2(OnConnectChanged,
               void(scoped_refptr<RemoteDevice> device, bool connected));
  MOCK_METHOD2(OnMtuChanged, void(scoped_refptr<RemoteDevice> device, int mtu));
  MOCK_METHOD2(OnServicesUpdated,
               void(scoped_refptr<RemoteDevice> device,
                    std::vector<scoped_refptr<RemoteService>> services));
  MOCK_METHOD3(OnCharacteristicNotification,
               void(scoped_refptr<RemoteDevice> device,
                    scoped_refptr<RemoteCharacteristic> characteristic,
                    std::vector<uint8_t> value));
};

std::vector<bluetooth_v2_shlib::Gatt::Service> GenerateServices() {
  std::vector<bluetooth_v2_shlib::Gatt::Service> ret;

  bluetooth_v2_shlib::Gatt::Service service;
  bluetooth_v2_shlib::Gatt::Characteristic characteristic;
  bluetooth_v2_shlib::Gatt::Descriptor descriptor;

  service.uuid = {{0x1}};
  service.handle = 0x1;
  service.primary = true;

  characteristic.uuid = {{0x1, 0x1}};
  characteristic.handle = 0x2;
  characteristic.permissions =
      static_cast<bluetooth_v2_shlib::Gatt::Permissions>(
          bluetooth_v2_shlib::Gatt::PERMISSION_READ |
          bluetooth_v2_shlib::Gatt::PERMISSION_WRITE);
  characteristic.properties = bluetooth_v2_shlib::Gatt::PROPERTY_NOTIFY;

  descriptor.uuid = {{0x1, 0x1, 0x1}};
  descriptor.handle = 0x3;
  descriptor.permissions = static_cast<bluetooth_v2_shlib::Gatt::Permissions>(
      bluetooth_v2_shlib::Gatt::PERMISSION_READ |
      bluetooth_v2_shlib::Gatt::PERMISSION_WRITE);
  characteristic.descriptors.push_back(descriptor);

  descriptor.uuid = RemoteDescriptor::kCccdUuid;
  descriptor.handle = 0x4;
  descriptor.permissions = static_cast<bluetooth_v2_shlib::Gatt::Permissions>(
      bluetooth_v2_shlib::Gatt::PERMISSION_READ |
      bluetooth_v2_shlib::Gatt::PERMISSION_WRITE);
  characteristic.descriptors.push_back(descriptor);
  service.characteristics.push_back(characteristic);

  characteristic.uuid = {{0x1, 0x2}};
  characteristic.handle = 0x5;
  characteristic.permissions =
      static_cast<bluetooth_v2_shlib::Gatt::Permissions>(
          bluetooth_v2_shlib::Gatt::PERMISSION_READ |
          bluetooth_v2_shlib::Gatt::PERMISSION_WRITE);
  characteristic.properties =
      static_cast<bluetooth_v2_shlib::Gatt::Properties>(0);
  characteristic.descriptors.clear();
  service.characteristics.push_back(characteristic);

  ret.push_back(service);

  service.uuid = {{0x2}};
  service.handle = 0x6;
  service.primary = true;
  service.characteristics.clear();
  ret.push_back(service);

  return ret;
}

class GattClientManagerTest : public ::testing::Test {
 public:
  void SetUp() override {
    fake_task_runner_ = new base::TestMockTimeTaskRunner();
    message_loop_ =
        std::make_unique<base::MessageLoop>(base::MessageLoop::TYPE_DEFAULT);
    message_loop_->SetTaskRunner(fake_task_runner_);
    gatt_client_ = std::make_unique<bluetooth_v2_shlib::MockGattClient>();
    gatt_client_manager_ =
        std::make_unique<GattClientManagerImpl>(gatt_client_.get());
    observer_ = std::make_unique<MockGattClientManagerObserver>();

    // Normally bluetooth_manager does this.
    gatt_client_->SetDelegate(gatt_client_manager_.get());
    gatt_client_manager_->Initialize(fake_task_runner_);
    gatt_client_manager_->AddObserver(observer_.get());
  }

  void TearDown() override {
    gatt_client_->SetDelegate(nullptr);
    gatt_client_manager_->RemoveObserver(observer_.get());
    gatt_client_manager_->Finalize();
    fake_task_runner_ = nullptr;
  }

  scoped_refptr<RemoteDevice> GetDevice(const bluetooth_v2_shlib::Addr& addr) {
    scoped_refptr<RemoteDevice> ret;
    gatt_client_manager_->GetDevice(
        addr, base::BindOnce(
                  [](scoped_refptr<RemoteDevice>* ret_ptr,
                     scoped_refptr<RemoteDevice> result) { *ret_ptr = result; },
                  &ret));

    return ret;
  }

  std::vector<scoped_refptr<RemoteService>> GetServices(RemoteDevice* device) {
    std::vector<scoped_refptr<RemoteService>> ret;
    device->GetServices(base::BindOnce(
        [](std::vector<scoped_refptr<RemoteService>>* ret_ptr,
           std::vector<scoped_refptr<RemoteService>> result) {
          *ret_ptr = result;
        },
        &ret));

    return ret;
  }

  scoped_refptr<RemoteService> GetServiceByUuid(
      RemoteDevice* device,
      const bluetooth_v2_shlib::Uuid& uuid) {
    scoped_refptr<RemoteService> ret;
    device->GetServiceByUuid(uuid, base::BindOnce(
                                       [](scoped_refptr<RemoteService>* ret_ptr,
                                          scoped_refptr<RemoteService> result) {
                                         *ret_ptr = result;
                                       },
                                       &ret));
    return ret;
  }

  void Connect(const bluetooth_v2_shlib::Addr& addr) {
    EXPECT_CALL(*gatt_client_, Connect(addr)).WillOnce(Return(true));
    scoped_refptr<RemoteDevice> device = GetDevice(addr);
    EXPECT_CALL(cb_, Run(true));
    device->Connect(cb_.Get());
    bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
        gatt_client_->delegate();
    EXPECT_CALL(*gatt_client_, GetServices(kTestAddr1)).WillOnce(Return(true));
    delegate->OnConnectChanged(addr, true /* status */, true /* connected */);
    delegate->OnGetServices(addr, {});
    ASSERT_TRUE(device->IsConnected());
  }

  scoped_refptr<base::TestMockTimeTaskRunner> fake_task_runner_;
  base::MockCallback<RemoteDevice::StatusCallback> cb_;
  std::unique_ptr<base::MessageLoop> message_loop_;
  std::unique_ptr<GattClientManagerImpl> gatt_client_manager_;
  std::unique_ptr<bluetooth_v2_shlib::MockGattClient> gatt_client_;
  std::unique_ptr<MockGattClientManagerObserver> observer_;
};

}  // namespace

TEST_F(GattClientManagerTest, RemoteDeviceConnect) {
  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();

  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);
  EXPECT_FALSE(device->IsConnected());
  EXPECT_EQ(kTestAddr1, device->addr());

  // These should fail if we're not connected.
  EXPECT_CALL(cb_, Run(false));
  device->Disconnect(cb_.Get());

  EXPECT_CALL(cb_, Run(false));
  device->CreateBond(cb_.Get());

  base::MockCallback<RemoteDevice::RssiCallback> rssi_cb;
  EXPECT_CALL(rssi_cb, Run(false, _));
  device->ReadRemoteRssi(rssi_cb.Get());

  EXPECT_CALL(cb_, Run(false));
  device->RequestMtu(512, cb_.Get());

  EXPECT_CALL(cb_, Run(false));
  device->ConnectionParameterUpdate(10, 10, 50, 100, cb_.Get());

  EXPECT_CALL(*gatt_client_, Connect(kTestAddr1)).WillOnce(Return(true));

  EXPECT_CALL(cb_, Run(true));
  device->Connect(cb_.Get());
  EXPECT_CALL(*gatt_client_, GetServices(kTestAddr1)).WillOnce(Return(true));
  delegate->OnConnectChanged(kTestAddr1, true /* status */,
                             true /* connected */);
  EXPECT_CALL(*observer_, OnConnectChanged(device, true));
  delegate->OnGetServices(kTestAddr1, {});

  EXPECT_TRUE(device->IsConnected());

  base::MockCallback<
      base::OnceCallback<void(std::vector<scoped_refptr<RemoteDevice>>)>>
      get_connected_callback;
  const std::vector<scoped_refptr<RemoteDevice>> kExpectedDevices({device});
  EXPECT_CALL(get_connected_callback, Run(kExpectedDevices));
  gatt_client_manager_->GetConnectedDevices(get_connected_callback.Get());

  base::RunLoop().RunUntilIdle();

  EXPECT_CALL(*gatt_client_, Disconnect(kTestAddr1)).WillOnce(Return(true));
  device->Disconnect({});
  EXPECT_TRUE(device->IsConnected());

  EXPECT_CALL(*observer_, OnConnectChanged(device, false));
  delegate->OnConnectChanged(kTestAddr1, true /* status */,
                             false /* connected */);
  EXPECT_FALSE(device->IsConnected());
  fake_task_runner_->RunUntilIdle();
}

TEST_F(GattClientManagerTest, RemoteDeviceBond) {
  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();

  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);
  Connect(kTestAddr1);
  EXPECT_FALSE(device->IsBonded());

  // CreateBond fails in the initial request.
  EXPECT_CALL(*gatt_client_, CreateBond(kTestAddr1)).WillOnce(Return(false));
  EXPECT_CALL(cb_, Run(false));
  device->CreateBond(cb_.Get());
  EXPECT_FALSE(device->IsBonded());

  // CreateBond fails in the callback.
  EXPECT_CALL(*gatt_client_, CreateBond(kTestAddr1)).WillOnce(Return(true));
  EXPECT_CALL(cb_, Run(false));
  device->CreateBond(cb_.Get());
  delegate->OnBondChanged(kTestAddr1, false /* status */, false /* bonded */);
  EXPECT_FALSE(device->IsBonded());

  // CreateBond succeeds.
  EXPECT_CALL(*gatt_client_, CreateBond(kTestAddr1)).WillOnce(Return(true));
  device->CreateBond(cb_.Get());
  EXPECT_CALL(cb_, Run(true));
  delegate->OnBondChanged(kTestAddr1, true /* status */, true /* bonded */);
  EXPECT_TRUE(device->IsBonded());

  // Bond with an already bonded device should fail.
  EXPECT_CALL(cb_, Run(false));
  device->CreateBond(cb_.Get());
  EXPECT_TRUE(device->IsBonded());

  // RemoveBond succeeds.
  EXPECT_CALL(*gatt_client_, RemoveBond(kTestAddr1)).WillOnce(Return(true));
  device->RemoveBond(cb_.Get());
  EXPECT_CALL(cb_, Run(true));
  delegate->OnBondChanged(kTestAddr1, false /* status */, false /* bonded */);
  EXPECT_FALSE(device->IsBonded());

  // RemoveBond from an unbonded device succeeds.
  EXPECT_CALL(*gatt_client_, RemoveBond(kTestAddr1)).WillOnce(Return(true));
  device->RemoveBond(cb_.Get());
  EXPECT_CALL(cb_, Run(true));
  delegate->OnBondChanged(kTestAddr1, false /* status */, false /* bonded */);
  EXPECT_FALSE(device->IsBonded());

  // CreateBond again succeeds.
  EXPECT_CALL(*gatt_client_, CreateBond(kTestAddr1)).WillOnce(Return(true));
  device->CreateBond(cb_.Get());
  EXPECT_CALL(cb_, Run(true));
  delegate->OnBondChanged(kTestAddr1, true /* status */, true /* bonded */);
  EXPECT_TRUE(device->IsBonded());

  // Device should remain bonded when it disconnects.
  EXPECT_CALL(*gatt_client_, Disconnect(kTestAddr1)).WillOnce(Return(true));
  device->Disconnect({});
  delegate->OnConnectChanged(kTestAddr1, true /* status */,
                             false /* connected */);
  EXPECT_FALSE(device->IsConnected());
  EXPECT_TRUE(device->IsBonded());

  // RemoveBond from a disconnected but bonded device.
  EXPECT_CALL(*gatt_client_, RemoveBond(kTestAddr1)).WillOnce(Return(true));
  device->RemoveBond(cb_.Get());
  EXPECT_CALL(cb_, Run(true));
  delegate->OnBondChanged(kTestAddr1, false /* status */, false /* bonded */);
  EXPECT_FALSE(device->IsBonded());

  fake_task_runner_->RunUntilIdle();
}

TEST_F(GattClientManagerTest, RemoteDeviceBondedOnInitialization) {
  // NotifyBonded at initialization.
  gatt_client_manager_->NotifyBonded(kTestAddr1);

  // Device should have updated the bonding state.
  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);
  EXPECT_FALSE(device->IsConnected());
  EXPECT_TRUE(device->IsBonded());

  Connect(kTestAddr1);
  EXPECT_TRUE(device->IsConnected());
  EXPECT_TRUE(device->IsBonded());

  fake_task_runner_->RunUntilIdle();
}

TEST_F(GattClientManagerTest, RemoteDeviceConnectConcurrent) {
  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();
  scoped_refptr<RemoteDevice> device1 = GetDevice(kTestAddr1);
  scoped_refptr<RemoteDevice> device2 = GetDevice(kTestAddr2);
  scoped_refptr<RemoteDevice> device3 = GetDevice(kTestAddr3);
  scoped_refptr<RemoteDevice> device4 = GetDevice(kTestAddr4);

  base::MockCallback<RemoteDevice::StatusCallback> cb1;
  base::MockCallback<RemoteDevice::StatusCallback> cb2;
  base::MockCallback<RemoteDevice::StatusCallback> cb3;
  base::MockCallback<RemoteDevice::StatusCallback> cb4;

  // Only the 1st Connect request will be executed immediately. The rest will be
  // queued.
  EXPECT_CALL(*gatt_client_, Connect(kTestAddr1)).WillOnce(Return(true));
  device1->Connect(cb1.Get());
  device2->Connect(cb2.Get());
  device3->Connect(cb3.Get());
  device4->Connect(cb4.Get());

  EXPECT_CALL(*gatt_client_, GetServices(kTestAddr1)).WillOnce(Return(true));
  delegate->OnConnectChanged(kTestAddr1, true /* status */,
                             true /* connected */);

  // Queued Connect requests will not be called until we receive OnGetServices
  // of the current Connect request if it is successful.
  EXPECT_CALL(cb1, Run(true));
  EXPECT_CALL(*gatt_client_, Connect(kTestAddr2)).WillOnce(Return(false));
  EXPECT_CALL(cb2, Run(false));
  // If the Connect request fails in the initial request (not in the callback),
  // the next queued request will be executed immediately.
  EXPECT_CALL(*gatt_client_, Connect(kTestAddr3)).WillOnce(Return(true));
  delegate->OnGetServices(kTestAddr1, {});

  EXPECT_CALL(cb3, Run(false));
  EXPECT_CALL(*gatt_client_, Connect(kTestAddr4)).WillOnce(Return(true));
  delegate->OnConnectChanged(kTestAddr3, true /* status */,
                             false /* connected */);

  EXPECT_CALL(*gatt_client_, GetServices(kTestAddr4)).WillOnce(Return(true));
  delegate->OnConnectChanged(kTestAddr4, true /* status */,
                             true /* connected */);

  EXPECT_CALL(cb4, Run(true));
  delegate->OnGetServices(kTestAddr4, {});

  EXPECT_TRUE(device1->IsConnected());
  EXPECT_FALSE(device2->IsConnected());
  EXPECT_FALSE(device3->IsConnected());
  EXPECT_TRUE(device4->IsConnected());

  base::MockCallback<base::OnceCallback<void(size_t)>>
      get_num_connected_callback;
  EXPECT_CALL(get_num_connected_callback, Run(2));
  gatt_client_manager_->GetNumConnected(get_num_connected_callback.Get());

  base::RunLoop().RunUntilIdle();
}

TEST_F(GattClientManagerTest, ConnectTimeout) {
  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);

  // Issue a Connect request
  EXPECT_CALL(*gatt_client_, Connect(kTestAddr1)).WillOnce(Return(true));
  device->Connect(cb_.Get());

  // Let Connect request timeout
  base::TestMockTimeTaskRunner::ScopedContext context(fake_task_runner_);
  // We should expect to receive Connect failure message
  EXPECT_CALL(cb_, Run(false));
  fake_task_runner_->FastForwardBy(GattClientManagerImpl::kConnectTimeout);
  EXPECT_FALSE(device->IsConnected());
}

TEST_F(GattClientManagerTest, GetServicesTimeout) {
  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();

  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);

  // Issue a Connect request and let Connect succeed
  EXPECT_CALL(*gatt_client_, Connect(kTestAddr1)).WillOnce(Return(true));
  device->Connect(cb_.Get());
  EXPECT_CALL(*gatt_client_, GetServices(kTestAddr1)).WillOnce(Return(true));
  delegate->OnConnectChanged(kTestAddr1, true /* status */,
                             true /* connected */);

  // Let GetServices request timeout
  base::TestMockTimeTaskRunner::ScopedContext context(fake_task_runner_);
  // We should request a disconnect.
  EXPECT_CALL(*gatt_client_, Disconnect(kTestAddr1)).WillOnce(Return(true));
  fake_task_runner_->FastForwardBy(GattClientManagerImpl::kConnectTimeout);

  // Make sure we issued a disconnect.
  testing::Mock::VerifyAndClearExpectations(gatt_client_.get());

  EXPECT_CALL(cb_, Run(false));
  delegate->OnConnectChanged(kTestAddr1, true /* status */,
                             false /* connected */);

  EXPECT_FALSE(device->IsConnected());
}

TEST_F(GattClientManagerTest, RemoteDeviceReadRssi) {
  static const int kRssi = -34;

  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();
  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);

  Connect(kTestAddr1);

  base::MockCallback<RemoteDevice::RssiCallback> rssi_cb;
  EXPECT_CALL(*gatt_client_, ReadRemoteRssi(kTestAddr1)).WillOnce(Return(true));
  device->ReadRemoteRssi(rssi_cb.Get());

  EXPECT_CALL(rssi_cb, Run(true, kRssi));
  delegate->OnReadRemoteRssi(kTestAddr1, true /* status */, kRssi);
}

TEST_F(GattClientManagerTest, ReadRemoteRssiTimeout) {
  static const int kRssi = -34;

  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();
  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);

  Connect(kTestAddr1);

  // Issue a ReadRemoteRssi request.
  base::MockCallback<RemoteDevice::RssiCallback> rssi_cb;
  EXPECT_CALL(*gatt_client_, ReadRemoteRssi(kTestAddr1)).WillOnce(Return(true));
  device->ReadRemoteRssi(rssi_cb.Get());

  // Let ReadRemoteRssi request timeout.
  base::TestMockTimeTaskRunner::ScopedContext context(fake_task_runner_);
  // We should expect to receive ReadRemoteRssi failure message.
  EXPECT_CALL(rssi_cb, Run(false, 0));
  fake_task_runner_->FastForwardBy(
      GattClientManagerImpl::kReadRemoteRssiTimeout);

  // The following callback should be ignored.
  delegate->OnReadRemoteRssi(kTestAddr1, true /* status */, kRssi);

  // Device should remain connected.
  EXPECT_TRUE(device->IsConnected());
}

TEST_F(GattClientManagerTest, RemoteDeviceReadRssiConcurrent) {
  static const int kRssi1 = -34;
  static const int kRssi3 = -68;

  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();
  scoped_refptr<RemoteDevice> device1 = GetDevice(kTestAddr1);
  scoped_refptr<RemoteDevice> device2 = GetDevice(kTestAddr2);
  scoped_refptr<RemoteDevice> device3 = GetDevice(kTestAddr3);

  base::MockCallback<RemoteDevice::RssiCallback> rssi_cb1;
  base::MockCallback<RemoteDevice::RssiCallback> rssi_cb2;
  base::MockCallback<RemoteDevice::RssiCallback> rssi_cb3;

  // Only the 1st ReadRemoteRssi request will be executed immediately. The rest
  // will be queued.
  EXPECT_CALL(*gatt_client_, ReadRemoteRssi(kTestAddr1)).WillOnce(Return(true));
  device1->ReadRemoteRssi(rssi_cb1.Get());
  device2->ReadRemoteRssi(rssi_cb2.Get());
  device3->ReadRemoteRssi(rssi_cb3.Get());

  // Queued ReadRemoteRssi requests will not be called until we receive
  // OnGetServices of the current Connect request if it is successful.
  EXPECT_CALL(rssi_cb1, Run(true, kRssi1));
  EXPECT_CALL(*gatt_client_, ReadRemoteRssi(kTestAddr2))
      .WillOnce(Return(false));
  EXPECT_CALL(rssi_cb2, Run(false, _));
  // If the ReadRemoteRssi request fails in the initial request (not in the
  // callback), the next queued request will be executed immediately.
  EXPECT_CALL(*gatt_client_, ReadRemoteRssi(kTestAddr3)).WillOnce(Return(true));
  delegate->OnReadRemoteRssi(kTestAddr1, true, kRssi1);

  EXPECT_CALL(rssi_cb3, Run(true, kRssi3));
  delegate->OnReadRemoteRssi(kTestAddr3, true, kRssi3);
}

TEST_F(GattClientManagerTest, RemoteDeviceRequestMtu) {
  static const int kMtu = 512;
  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();
  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);
  Connect(kTestAddr1);

  EXPECT_EQ(RemoteDevice::kDefaultMtu, device->GetMtu());
  EXPECT_CALL(*gatt_client_, RequestMtu(kTestAddr1, kMtu))
      .WillOnce(Return(true));
  EXPECT_CALL(cb_, Run(true));
  device->RequestMtu(kMtu, cb_.Get());
  EXPECT_CALL(*observer_, OnMtuChanged(device, kMtu));
  delegate->OnMtuChanged(kTestAddr1, true, kMtu);
  EXPECT_EQ(kMtu, device->GetMtu());
  fake_task_runner_->RunUntilIdle();
}

TEST_F(GattClientManagerTest, RemoteDeviceConnectionParameterUpdate) {
  const int kMinInterval = 10;
  const int kMaxInterval = 10;
  const int kLatency = 50;
  const int kTimeout = 100;

  Connect(kTestAddr1);

  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);
  EXPECT_CALL(*gatt_client_,
              ConnectionParameterUpdate(kTestAddr1, kMinInterval, kMaxInterval,
                                        kLatency, kTimeout))
      .WillOnce(Return(true));
  EXPECT_CALL(cb_, Run(true));
  device->ConnectionParameterUpdate(kMinInterval, kMaxInterval, kLatency,
                                    kTimeout, cb_.Get());
}

TEST_F(GattClientManagerTest, RemoteDeviceServices) {
  const auto kServices = GenerateServices();
  Connect(kTestAddr1);
  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);
  std::vector<scoped_refptr<RemoteService>> services;
  EXPECT_EQ(0ul, GetServices(device.get()).size());

  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();
  delegate->OnServicesAdded(kTestAddr1, kServices);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(kServices.size(), GetServices(device.get()).size());
  for (const auto& service : kServices) {
    scoped_refptr<RemoteService> remote_service =
        GetServiceByUuid(device.get(), service.uuid);
    ASSERT_TRUE(remote_service);
    EXPECT_EQ(service.uuid, remote_service->uuid());
    EXPECT_EQ(service.handle, remote_service->handle());
    EXPECT_EQ(service.primary, remote_service->primary());
    EXPECT_EQ(service.characteristics.size(),
              remote_service->GetCharacteristics().size());

    for (const auto& characteristic : service.characteristics) {
      scoped_refptr<RemoteCharacteristic> remote_char =
          remote_service->GetCharacteristicByUuid(characteristic.uuid);
      ASSERT_TRUE(remote_char);
      EXPECT_EQ(characteristic.uuid, remote_char->uuid());
      EXPECT_EQ(characteristic.handle, remote_char->handle());
      EXPECT_EQ(characteristic.permissions, remote_char->permissions());
      EXPECT_EQ(characteristic.properties, remote_char->properties());
      EXPECT_EQ(characteristic.descriptors.size(),
                remote_char->GetDescriptors().size());

      for (const auto& descriptor : characteristic.descriptors) {
        scoped_refptr<RemoteDescriptor> remote_desc =
            remote_char->GetDescriptorByUuid(descriptor.uuid);
        ASSERT_TRUE(remote_desc);
        EXPECT_EQ(descriptor.uuid, remote_desc->uuid());
        EXPECT_EQ(descriptor.handle, remote_desc->handle());
        EXPECT_EQ(descriptor.permissions, remote_desc->permissions());
      }
    }
  }
}

TEST_F(GattClientManagerTest, RemoteDeviceCharacteristic) {
  const std::vector<uint8_t> kTestData1 = {0x1, 0x2, 0x3};
  const std::vector<uint8_t> kTestData2 = {0x4, 0x5, 0x6};
  const std::vector<uint8_t> kTestData3 = {0x7, 0x8, 0x9};
  const auto kServices = GenerateServices();
  const bluetooth_v2_shlib::Gatt::Client::AuthReq kAuthReq =
      bluetooth_v2_shlib::Gatt::Client::AUTH_REQ_MITM;
  const bluetooth_v2_shlib::Gatt::WriteType kWriteType =
      bluetooth_v2_shlib::Gatt::WRITE_TYPE_DEFAULT;

  Connect(kTestAddr1);
  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);
  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();
  delegate->OnServicesAdded(kTestAddr1, kServices);
  std::vector<scoped_refptr<RemoteService>> services =
      GetServices(device.get());
  ASSERT_EQ(kServices.size(), services.size());

  auto service = services[0];
  std::vector<scoped_refptr<RemoteCharacteristic>> characteristics =
      service->GetCharacteristics();
  ASSERT_GE(characteristics.size(), 1ul);
  auto characteristic = characteristics[0];

  EXPECT_CALL(*gatt_client_,
              WriteCharacteristic(kTestAddr1, characteristic->characteristic(),
                                  kAuthReq, kWriteType, kTestData1))
      .WillOnce(Return(true));

  EXPECT_CALL(cb_, Run(true));
  characteristic->WriteAuth(kAuthReq, kWriteType, kTestData1, cb_.Get());
  delegate->OnCharacteristicWriteResponse(kTestAddr1, true,
                                          characteristic->handle());

  EXPECT_CALL(*gatt_client_,
              ReadCharacteristic(kTestAddr1, characteristic->characteristic(),
                                 kAuthReq))
      .WillOnce(Return(true));

  base::MockCallback<RemoteCharacteristic::ReadCallback> read_cb;
  EXPECT_CALL(read_cb, Run(true, kTestData2));
  characteristic->ReadAuth(kAuthReq, read_cb.Get());
  delegate->OnCharacteristicReadResponse(kTestAddr1, true,
                                         characteristic->handle(), kTestData2);

  EXPECT_CALL(*gatt_client_,
              SetCharacteristicNotification(
                  kTestAddr1, characteristic->characteristic(), true))
      .WillOnce(Return(true));

  EXPECT_CALL(cb_, Run(true));
  characteristic->SetNotification(true, cb_.Get());

  EXPECT_CALL(*observer_,
              OnCharacteristicNotification(device, characteristic, kTestData3));
  delegate->OnNotification(kTestAddr1, characteristic->handle(), kTestData3);
  fake_task_runner_->RunUntilIdle();
}

TEST_F(GattClientManagerTest,
       RemoteDeviceCharacteristicSetRegisterNotification) {
  const std::vector<uint8_t> kTestData1 = {0x1, 0x2, 0x3};
  const auto kServices = GenerateServices();
  Connect(kTestAddr1);
  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);
  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();
  delegate->OnServicesAdded(kTestAddr1, kServices);
  std::vector<scoped_refptr<RemoteService>> services =
      GetServices(device.get());
  ASSERT_EQ(kServices.size(), services.size());

  scoped_refptr<RemoteService> service = services[0];
  std::vector<scoped_refptr<RemoteCharacteristic>> characteristics =
      service->GetCharacteristics();
  ASSERT_GE(characteristics.size(), 1ul);
  scoped_refptr<RemoteCharacteristic> characteristic = characteristics[0];

  scoped_refptr<RemoteDescriptor> cccd =
      characteristic->GetDescriptorByUuid(RemoteDescriptor::kCccdUuid);
  ASSERT_TRUE(cccd);

  EXPECT_CALL(*gatt_client_,
              SetCharacteristicNotification(
                  kTestAddr1, characteristic->characteristic(), true))
      .WillOnce(Return(true));
  std::vector<uint8_t> cccd_enable_notification = {
      std::begin(bluetooth::RemoteDescriptor::kEnableNotificationValue),
      std::end(bluetooth::RemoteDescriptor::kEnableNotificationValue)};
  EXPECT_CALL(*gatt_client_, WriteDescriptor(kTestAddr1, cccd->descriptor(), _,
                                             cccd_enable_notification))
      .WillOnce(Return(true));

  characteristic->SetRegisterNotification(true, cb_.Get());
  EXPECT_CALL(cb_, Run(true));
  delegate->OnDescriptorWriteResponse(kTestAddr1, true, cccd->handle());

  EXPECT_CALL(*observer_,
              OnCharacteristicNotification(device, characteristic, kTestData1));
  delegate->OnNotification(kTestAddr1, characteristic->handle(), kTestData1);
  fake_task_runner_->RunUntilIdle();
}

TEST_F(GattClientManagerTest, RemoteDeviceDescriptor) {
  const std::vector<uint8_t> kTestData1 = {0x1, 0x2, 0x3};
  const std::vector<uint8_t> kTestData2 = {0x4, 0x5, 0x6};
  const bluetooth_v2_shlib::Gatt::Client::AuthReq kAuthReq =
      bluetooth_v2_shlib::Gatt::Client::AUTH_REQ_MITM;
  const auto kServices = GenerateServices();
  Connect(kTestAddr1);
  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);
  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();
  delegate->OnServicesAdded(kTestAddr1, kServices);
  std::vector<scoped_refptr<RemoteService>> services =
      GetServices(device.get());
  ASSERT_EQ(kServices.size(), services.size());

  auto service = services[0];
  std::vector<scoped_refptr<RemoteCharacteristic>> characteristics =
      service->GetCharacteristics();
  ASSERT_GE(characteristics.size(), 1ul);
  auto characteristic = characteristics[0];

  std::vector<scoped_refptr<RemoteDescriptor>> descriptors =
      characteristic->GetDescriptors();
  ASSERT_GE(descriptors.size(), 1ul);
  auto descriptor = descriptors[0];

  EXPECT_CALL(*gatt_client_,
              WriteDescriptor(kTestAddr1, descriptor->descriptor(), kAuthReq,
                              kTestData1))
      .WillOnce(Return(true));

  EXPECT_CALL(cb_, Run(true));
  descriptor->WriteAuth(kAuthReq, kTestData1, cb_.Get());
  delegate->OnDescriptorWriteResponse(kTestAddr1, true, descriptor->handle());

  EXPECT_CALL(*gatt_client_,
              ReadDescriptor(kTestAddr1, descriptor->descriptor(), kAuthReq))
      .WillOnce(Return(true));

  base::MockCallback<RemoteDescriptor::ReadCallback> read_cb;
  EXPECT_CALL(read_cb, Run(true, kTestData2));
  descriptor->ReadAuth(kAuthReq, read_cb.Get());
  delegate->OnDescriptorReadResponse(kTestAddr1, true, descriptor->handle(),
                                     kTestData2);
}

TEST_F(GattClientManagerTest, FakeCccd) {
  std::vector<bluetooth_v2_shlib::Gatt::Service> input_services(1);
  input_services[0].uuid = {{0x1}};
  input_services[0].handle = 0x1;
  input_services[0].primary = true;

  bluetooth_v2_shlib::Gatt::Characteristic input_characteristic;
  input_characteristic.uuid = {{0x1, 0x1}};
  input_characteristic.handle = 0x2;
  input_characteristic.permissions = bluetooth_v2_shlib::Gatt::PERMISSION_READ;
  input_characteristic.properties = bluetooth_v2_shlib::Gatt::PROPERTY_NOTIFY;
  input_services[0].characteristics.push_back(input_characteristic);

  // Test indicate as well
  input_characteristic.uuid = {{0x1, 0x2}};
  input_characteristic.handle = 0x3;
  input_characteristic.properties = bluetooth_v2_shlib::Gatt::PROPERTY_INDICATE;
  input_services[0].characteristics.push_back(input_characteristic);

  Connect(kTestAddr1);
  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);
  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();
  delegate->OnServicesAdded(kTestAddr1, input_services);
  std::vector<scoped_refptr<RemoteService>> services =
      GetServices(device.get());
  ASSERT_EQ(input_services.size(), services.size());

  auto service = services[0];
  std::vector<scoped_refptr<RemoteCharacteristic>> characteristics =
      service->GetCharacteristics();
  ASSERT_EQ(2u, characteristics.size());
  for (const auto& characteristic : characteristics) {
    // A CCCD should have been created.
    std::vector<scoped_refptr<RemoteDescriptor>> descriptors =
        characteristic->GetDescriptors();
    ASSERT_EQ(descriptors.size(), 1ul);
    auto descriptor = descriptors[0];
    EXPECT_EQ(RemoteDescriptor::kCccdUuid, descriptor->uuid());
    EXPECT_EQ(static_cast<bluetooth_v2_shlib::Gatt::Permissions>(
                  bluetooth_v2_shlib::Gatt::PERMISSION_READ |
                  bluetooth_v2_shlib::Gatt::PERMISSION_WRITE),
              descriptor->permissions());
  }
}

TEST_F(GattClientManagerTest, WriteType) {
  const std::vector<uint8_t> kTestData1 = {0x1, 0x2, 0x3};

  bluetooth_v2_shlib::Gatt::Service service;
  bluetooth_v2_shlib::Gatt::Characteristic characteristic;

  service.uuid = {{0x1}};
  service.handle = 0x1;
  service.primary = true;

  characteristic.uuid = {{0x1, 0x1}};
  characteristic.handle = 0x2;
  characteristic.permissions = bluetooth_v2_shlib::Gatt::PERMISSION_WRITE;
  characteristic.properties = bluetooth_v2_shlib::Gatt::PROPERTY_WRITE;
  service.characteristics.push_back(characteristic);

  characteristic.uuid = {{0x1, 0x2}};
  characteristic.handle = 0x3;
  characteristic.permissions = bluetooth_v2_shlib::Gatt::PERMISSION_WRITE;
  characteristic.properties =
      bluetooth_v2_shlib::Gatt::PROPERTY_WRITE_NO_RESPONSE;
  service.characteristics.push_back(characteristic);

  characteristic.uuid = {{0x1, 0x3}};
  characteristic.handle = 0x4;
  characteristic.permissions = bluetooth_v2_shlib::Gatt::PERMISSION_WRITE;
  characteristic.properties = bluetooth_v2_shlib::Gatt::PROPERTY_SIGNED_WRITE;
  service.characteristics.push_back(characteristic);

  Connect(kTestAddr1);
  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();
  delegate->OnServicesAdded(kTestAddr1, {service});

  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);

  std::vector<scoped_refptr<RemoteService>> services =
      GetServices(device.get());
  ASSERT_EQ(1u, services.size());

  std::vector<scoped_refptr<RemoteCharacteristic>> characteristics =
      services[0]->GetCharacteristics();
  ASSERT_EQ(3u, characteristics.size());

  using WriteType = bluetooth_v2_shlib::Gatt::WriteType;

  // The current implementation of RemoteDevice will put the characteristics in
  // the order reported by libcast_bluetooth.
  const WriteType kWriteTypes[] = {WriteType::WRITE_TYPE_DEFAULT,
                                   WriteType::WRITE_TYPE_NO_RESPONSE,
                                   WriteType::WRITE_TYPE_SIGNED};

  for (size_t i = 0; i < characteristics.size(); ++i) {
    const auto& characteristic = characteristics[i];
    EXPECT_CALL(
        *gatt_client_,
        WriteCharacteristic(kTestAddr1, characteristic->characteristic(),
                            bluetooth_v2_shlib::Gatt::Client::AUTH_REQ_NONE,
                            kWriteTypes[i], kTestData1))
        .WillOnce(Return(true));

    base::MockCallback<RemoteCharacteristic::StatusCallback> write_cb;
    EXPECT_CALL(write_cb, Run(true));
    characteristic->Write(kTestData1, write_cb.Get());
    delegate->OnCharacteristicWriteResponse(kTestAddr1, true,
                                            characteristic->handle());
  }
}

TEST_F(GattClientManagerTest, ConnectMultiple) {
  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();
  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);
  for (size_t i = 0; i < 5; ++i) {
    Connect(kTestAddr1);
    EXPECT_TRUE(device->IsConnected());
    EXPECT_CALL(*gatt_client_, Disconnect(kTestAddr1)).WillOnce(Return(true));
    device->Disconnect({});
    delegate->OnConnectChanged(kTestAddr1, true /* status */,
                               false /* connected */);
    EXPECT_FALSE(device->IsConnected());
  }
}

TEST_F(GattClientManagerTest, GetServicesFailOnConnect) {
  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);
  EXPECT_CALL(*gatt_client_, Connect(kTestAddr1)).WillOnce(Return(true));
  device->Connect(cb_.Get());
  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();

  EXPECT_CALL(cb_, Run(false));
  EXPECT_CALL(*gatt_client_, GetServices(kTestAddr1)).WillOnce(Return(false));
  delegate->OnConnectChanged(kTestAddr1, true /* status */,
                             true /* connected */);
  EXPECT_FALSE(device->IsConnected());
}

TEST_F(GattClientManagerTest, GetServicesSuccessAfterConnectCallback) {
  const auto kServices = GenerateServices();
  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);

  // Callback that checks when Connect()'s callback returns, GetServices returns
  // the correct services.
  bool cb_called = false;
  auto cb = base::BindOnce(
      [](GattClientManagerTest* gcmt,
         const std::vector<bluetooth_v2_shlib::Gatt::Service>*
             expected_services,
         bool* cb_called, bool success) {
        EXPECT_TRUE(success);
        *cb_called = true;

        auto device = gcmt->GetDevice(kTestAddr1);
        auto services = gcmt->GetServices(device.get());
        EXPECT_EQ(expected_services->size(), services.size());
      },
      this, &kServices, &cb_called);
  EXPECT_CALL(*gatt_client_, Connect(kTestAddr1)).WillOnce(Return(true));
  device->Connect(std::move(cb));

  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();
  EXPECT_CALL(*gatt_client_, GetServices(kTestAddr1)).WillOnce(Return(true));
  delegate->OnConnectChanged(kTestAddr1, true /* status */,
                             true /* connected */);

  // Connect's callback should not be called until service discovery is
  // complete.
  EXPECT_FALSE(cb_called);
  delegate->OnGetServices(kTestAddr1, kServices);
  EXPECT_TRUE(cb_called);
}

TEST_F(GattClientManagerTest, Queuing) {
  const std::vector<uint8_t> kTestData1 = {0x1, 0x2, 0x3};
  const std::vector<uint8_t> kTestData2 = {0x4, 0x5, 0x6};
  const std::vector<uint8_t> kTestData3 = {0x7, 0x8, 0x9};
  const auto kServices = GenerateServices();
  const bluetooth_v2_shlib::Gatt::Client::AuthReq kAuthReq =
      bluetooth_v2_shlib::Gatt::Client::AUTH_REQ_MITM;
  const bluetooth_v2_shlib::Gatt::WriteType kWriteType =
      bluetooth_v2_shlib::Gatt::WRITE_TYPE_DEFAULT;

  Connect(kTestAddr1);
  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);
  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();
  delegate->OnServicesAdded(kTestAddr1, kServices);
  std::vector<scoped_refptr<RemoteService>> services =
      GetServices(device.get());
  ASSERT_EQ(kServices.size(), services.size());

  auto service = services[0];
  std::vector<scoped_refptr<RemoteCharacteristic>> characteristics =
      service->GetCharacteristics();
  ASSERT_GE(characteristics.size(), 2ul);
  auto characteristic1 = characteristics[0];
  auto characteristic2 = characteristics[1];

  // Issue a write to one characteristic.
  EXPECT_CALL(*gatt_client_,
              WriteCharacteristic(kTestAddr1, characteristic1->characteristic(),
                                  kAuthReq, kWriteType, kTestData1))
      .WillOnce(Return(true));
  characteristic1->WriteAuth(kAuthReq, kWriteType, kTestData1, cb_.Get());

  // Issue a read to another characteristic. The shlib should not get the call
  // until after the read's callback.
  EXPECT_CALL(*gatt_client_,
              ReadCharacteristic(kTestAddr1, characteristic2->characteristic(),
                                 kAuthReq))
      .Times(0);
  base::MockCallback<RemoteCharacteristic::ReadCallback> read_cb;
  characteristic2->ReadAuth(kAuthReq, read_cb.Get());

  EXPECT_CALL(cb_, Run(true));
  EXPECT_CALL(*gatt_client_,
              ReadCharacteristic(kTestAddr1, characteristic2->characteristic(),
                                 kAuthReq))
      .WillOnce(Return(true));
  delegate->OnCharacteristicWriteResponse(kTestAddr1, true,
                                          characteristic1->handle());

  EXPECT_CALL(read_cb, Run(true, kTestData2));
  delegate->OnCharacteristicReadResponse(kTestAddr1, true,
                                         characteristic2->handle(), kTestData2);
  base::RunLoop().RunUntilIdle();
}

TEST_F(GattClientManagerTest, CommandTimeout) {
  const std::vector<uint8_t> kTestData = {0x7, 0x8, 0x9};
  const auto kServices = GenerateServices();
  const auto kAuthReq = bluetooth_v2_shlib::Gatt::Client::AUTH_REQ_MITM;
  const auto kWriteType = bluetooth_v2_shlib::Gatt::WRITE_TYPE_DEFAULT;

  // Connect a device and get services.
  Connect(kTestAddr1);
  scoped_refptr<RemoteDevice> device = GetDevice(kTestAddr1);
  bluetooth_v2_shlib::Gatt::Client::Delegate* delegate =
      gatt_client_->delegate();
  delegate->OnServicesAdded(kTestAddr1, kServices);
  std::vector<scoped_refptr<RemoteService>> services =
      GetServices(device.get());
  ASSERT_EQ(kServices.size(), services.size());

  auto service = services[0];
  std::vector<scoped_refptr<RemoteCharacteristic>> characteristics =
      service->GetCharacteristics();
  ASSERT_GE(characteristics.size(), 1ul);
  auto characteristic1 = characteristics[0];

  // Issue a write to one characteristic.
  EXPECT_CALL(*gatt_client_,
              WriteCharacteristic(kTestAddr1, characteristic1->characteristic(),
                                  kAuthReq, kWriteType, kTestData))
      .WillOnce(Return(true));
  characteristic1->WriteAuth(kAuthReq, kWriteType, kTestData, cb_.Get());

  // Let the command timeout
  base::TestMockTimeTaskRunner::ScopedContext context(fake_task_runner_);
  // We should request a disconnect.
  EXPECT_CALL(*gatt_client_, Disconnect(kTestAddr1)).WillOnce(Return(true));
  fake_task_runner_->FastForwardBy(RemoteDeviceImpl::kCommandTimeout);

  // Make sure we issued a disconnect.
  testing::Mock::VerifyAndClearExpectations(gatt_client_.get());

  // The operation should fail.
  EXPECT_CALL(cb_, Run(false));
  delegate->OnConnectChanged(kTestAddr1, true /* status */,
                             false /* connected */);
}

}  // namespace bluetooth
}  // namespace chromecast
