// Copyright 2018 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 "remote_service_manager.h"

#include <fbl/macros.h>

#include <vector>

#include "fake_client.h"
#include "lib/gtest/test_loop_fixture.h"
#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"

namespace bt {
namespace gatt {

// This must be in the correct namespace for it to be visible to EXPECT_EQ.
static bool operator==(const CharacteristicData& chrc1,
                       const CharacteristicData& chrc2) {
  return chrc1.properties == chrc2.properties && chrc1.handle == chrc2.handle &&
         chrc1.value_handle == chrc2.value_handle && chrc1.type == chrc2.type;
}

// This must be in the correct namespace for it to be visible to EXPECT_EQ.
static bool operator==(const DescriptorData& desc1,
                       const DescriptorData& desc2) {
  return desc1.handle == desc2.handle && desc1.type == desc2.type;
}

namespace internal {
namespace {

constexpr UUID kTestServiceUuid1((uint16_t)0xbeef);
constexpr UUID kTestServiceUuid2((uint16_t)0xcafe);
constexpr UUID kTestUuid3((uint16_t)0xfefe);
constexpr UUID kTestUuid4((uint16_t)0xefef);

const auto kCCCNotifyValue = CreateStaticByteBuffer(0x01, 0x00);
const auto kCCCIndicateValue = CreateStaticByteBuffer(0x02, 0x00);

void NopStatusCallback(att::Status) {}
void NopValueCallback(const ByteBuffer&) {}

class GATT_RemoteServiceManagerTest : public ::gtest::TestLoopFixture {
 public:
  GATT_RemoteServiceManagerTest() = default;
  ~GATT_RemoteServiceManagerTest() override = default;

 protected:
  void SetUp() override {
    auto client = std::make_unique<testing::FakeClient>(dispatcher());
    fake_client_ = client.get();

    mgr_ =
        std::make_unique<RemoteServiceManager>(std::move(client), dispatcher());
  }

  void TearDown() override {
    // Clear any previous expectations that are based on the ATT Write Request,
    // so that write requests sent during RemoteService::ShutDown() are ignored.
    fake_client()->set_write_request_callback({});
    mgr_ = nullptr;
  }

  // Initializes a RemoteService based on |data|.
  fbl::RefPtr<RemoteService> SetUpFakeService(const ServiceData& data) {
    std::vector<ServiceData> fake_services{{data}};
    fake_client()->set_primary_services(std::move(fake_services));

    mgr()->Initialize(NopStatusCallback);

    ServiceList services;
    mgr()->ListServices(std::vector<UUID>(),
                        [&services](auto status, ServiceList cb_services) {
                          services = std::move(cb_services);
                        });

    RunLoopUntilIdle();

    ZX_DEBUG_ASSERT(services.size() == 1u);
    return services[0];
  }

  // Discover the characteristics of |service| based on the given |fake_data|.
  void SetupCharacteristics(
      fbl::RefPtr<RemoteService> service,
      std::vector<CharacteristicData> fake_chrs,
      std::vector<DescriptorData> fake_descrs = std::vector<DescriptorData>()) {
    ZX_DEBUG_ASSERT(service);

    fake_client()->set_characteristics(std::move(fake_chrs));
    fake_client()->set_descriptors(std::move(fake_descrs));
    fake_client()->set_characteristic_discovery_status(att::Status());

    service->DiscoverCharacteristics([](auto, const auto&) {});
    RunLoopUntilIdle();
  }

  // Create a fake service with one notifiable characteristic.
  fbl::RefPtr<RemoteService> SetupNotifiableService() {
    ServiceData data(1, 4, kTestServiceUuid1);
    auto service = SetUpFakeService(data);

    CharacteristicData chr(Property::kNotify, 2, 3, kTestUuid3);
    DescriptorData desc(4, types::kClientCharacteristicConfig);
    SetupCharacteristics(service, {{chr}}, {{desc}});

    fake_client()->set_write_request_callback(
        [&](att::Handle, const auto&, auto status_callback) {
          status_callback(att::Status());
        });

    RunLoopUntilIdle();

    return service;
  }

  void EnableNotifications(
      fbl::RefPtr<RemoteService> service, IdType chr_id,
      att::Status* out_status, IdType* out_id,
      RemoteService::ValueCallback callback = NopValueCallback) {
    ZX_DEBUG_ASSERT(out_status);
    ZX_DEBUG_ASSERT(out_id);
    service->EnableNotifications(chr_id, std::move(callback),
                                 [&](att::Status cb_status, IdType cb_id) {
                                   *out_status = cb_status;
                                   *out_id = cb_id;
                                 });
    RunLoopUntilIdle();
  }

  RemoteServiceManager* mgr() const { return mgr_.get(); }
  testing::FakeClient* fake_client() const { return fake_client_; }

 private:
  std::unique_ptr<RemoteServiceManager> mgr_;

  // The memory is owned by |mgr_|.
  testing::FakeClient* fake_client_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(GATT_RemoteServiceManagerTest);
};

TEST_F(GATT_RemoteServiceManagerTest, InitializeNoServices) {
  std::vector<fbl::RefPtr<RemoteService>> services;
  mgr()->set_service_watcher(
      [&services](auto svc) { services.push_back(svc); });

  att::Status status(HostError::kFailed);
  mgr()->Initialize([&status](att::Status val) { status = val; });

  RunLoopUntilIdle();

  EXPECT_TRUE(status);
  EXPECT_TRUE(services.empty());

  mgr()->ListServices(std::vector<UUID>(),
                      [&services](auto status, ServiceList cb_services) {
                        services = std::move(cb_services);
                      });
  EXPECT_TRUE(services.empty());
}

TEST_F(GATT_RemoteServiceManagerTest, Initialize) {
  ServiceData svc1(1, 1, kTestServiceUuid1);
  ServiceData svc2(2, 2, kTestServiceUuid2);
  std::vector<ServiceData> fake_services{{svc1, svc2}};
  fake_client()->set_primary_services(std::move(fake_services));

  ServiceList services;
  mgr()->set_service_watcher(
      [&services](auto svc) { services.push_back(svc); });

  att::Status status(HostError::kFailed);
  mgr()->Initialize([&status](att::Status val) { status = val; });

  RunLoopUntilIdle();

  EXPECT_TRUE(status);
  EXPECT_EQ(2u, services.size());
  EXPECT_EQ(svc1.range_start, services[0]->handle());
  EXPECT_EQ(svc2.range_start, services[1]->handle());
  EXPECT_EQ(svc1.type, services[0]->uuid());
  EXPECT_EQ(svc2.type, services[1]->uuid());
}

TEST_F(GATT_RemoteServiceManagerTest, InitializeFailure) {
  fake_client()->set_service_discovery_status(
      att::Status(att::ErrorCode::kRequestNotSupported));

  ServiceList watcher_services;
  mgr()->set_service_watcher(
      [&watcher_services](auto svc) { watcher_services.push_back(svc); });

  ServiceList services;
  mgr()->ListServices(std::vector<UUID>(),
                      [&services](auto status, ServiceList cb_services) {
                        services = std::move(cb_services);
                      });
  ASSERT_TRUE(services.empty());

  att::Status status(HostError::kFailed);
  mgr()->Initialize([&status](att::Status val) { status = val; });

  RunLoopUntilIdle();

  EXPECT_FALSE(status);
  EXPECT_TRUE(status.is_protocol_error());
  EXPECT_EQ(att::ErrorCode::kRequestNotSupported, status.protocol_error());
  EXPECT_TRUE(services.empty());
  EXPECT_TRUE(watcher_services.empty());
}

TEST_F(GATT_RemoteServiceManagerTest, ListServicesBeforeInit) {
  ServiceData svc(1, 1, kTestServiceUuid1);
  std::vector<ServiceData> fake_services{{svc}};
  fake_client()->set_primary_services(std::move(fake_services));

  ServiceList services;
  mgr()->ListServices(std::vector<UUID>(),
                      [&services](auto status, ServiceList cb_services) {
                        services = std::move(cb_services);
                      });
  EXPECT_TRUE(services.empty());

  att::Status status(HostError::kFailed);
  mgr()->Initialize([&status](att::Status val) { status = val; });

  RunLoopUntilIdle();

  EXPECT_TRUE(status);
  EXPECT_EQ(1u, services.size());
  EXPECT_EQ(svc.range_start, services[0]->handle());
  EXPECT_EQ(svc.type, services[0]->uuid());
}

TEST_F(GATT_RemoteServiceManagerTest, ListServicesAfterInit) {
  ServiceData svc(1, 1, kTestServiceUuid1);
  std::vector<ServiceData> fake_services{{svc}};
  fake_client()->set_primary_services(std::move(fake_services));

  att::Status status(HostError::kFailed);
  mgr()->Initialize([&status](att::Status val) { status = val; });

  RunLoopUntilIdle();

  ASSERT_TRUE(status);

  ServiceList services;
  mgr()->ListServices(std::vector<UUID>(),
                      [&services](auto status, ServiceList cb_services) {
                        services = std::move(cb_services);
                      });
  EXPECT_EQ(1u, services.size());
  EXPECT_EQ(svc.range_start, services[0]->handle());
  EXPECT_EQ(svc.type, services[0]->uuid());
}

TEST_F(GATT_RemoteServiceManagerTest, ListServicesByUuid) {
  std::vector<UUID> uuids{kTestServiceUuid1};

  ServiceData svc1(1, 1, kTestServiceUuid1);
  ServiceData svc2(2, 2, kTestServiceUuid2);
  std::vector<ServiceData> fake_services{{svc1, svc2}};
  fake_client()->set_primary_services(std::move(fake_services));

  att::Status list_services_status;
  ServiceList services;
  mgr()->set_service_watcher(
      [&services](auto svc) { services.push_back(svc); });
  mgr()->ListServices(std::move(uuids),
                      [&](att::Status cb_status, ServiceList cb_services) {
                        list_services_status = cb_status;
                        services = std::move(cb_services);
                      });
  ASSERT_TRUE(services.empty());

  att::Status status(HostError::kFailed);
  mgr()->Initialize([&status](att::Status val) { status = val; });

  RunLoopUntilIdle();

  EXPECT_TRUE(status);
  EXPECT_TRUE(list_services_status);
  EXPECT_EQ(1u, services.size());
  EXPECT_EQ(svc1.range_start, services[0]->handle());
  EXPECT_EQ(svc1.type, services[0]->uuid());
}

TEST_F(GATT_RemoteServiceManagerTest, DiscoverCharacteristicsAfterShutDown) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  service->ShutDown();

  att::Status status;
  size_t chrcs_size;
  service->DiscoverCharacteristics(
      [&](att::Status cb_status, const auto& chrcs) {
        status = cb_status;
        chrcs_size = chrcs.size();
      });

  RunLoopUntilIdle();
  EXPECT_FALSE(status);
  EXPECT_EQ(HostError::kFailed, status.error());
  EXPECT_EQ(0u, chrcs_size);
  EXPECT_EQ(0u, fake_client()->chrc_discovery_count());
  EXPECT_FALSE(service->IsDiscovered());
}

TEST_F(GATT_RemoteServiceManagerTest, DiscoverCharacteristicsSuccess) {
  ServiceData data(1, 5, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData fake_chrc1(0, 2, 3, kTestUuid3);
  CharacteristicData fake_chrc2(0, 4, 5, kTestUuid4);
  std::vector<CharacteristicData> fake_chrcs{{fake_chrc1, fake_chrc2}};
  fake_client()->set_characteristics(std::move(fake_chrcs));

  att::Status status1(HostError::kFailed);
  service->DiscoverCharacteristics(
      [&](att::Status cb_status, const auto& chrcs) {
        status1 = cb_status;
        EXPECT_EQ(2u, chrcs.size());

        EXPECT_EQ(0u, chrcs[0].id());
        EXPECT_EQ(1u, chrcs[1].id());

        EXPECT_EQ(fake_chrc1, chrcs[0].info());
        EXPECT_EQ(fake_chrc2, chrcs[1].info());
      });

  // Queue a second request.
  att::Status status2(HostError::kFailed);
  RemoteCharacteristicList chrcs2;
  service->DiscoverCharacteristics(
      [&](att::Status cb_status, const auto& chrcs) {
        status2 = cb_status;
        EXPECT_EQ(2u, chrcs.size());

        EXPECT_EQ(0u, chrcs[0].id());
        EXPECT_EQ(1u, chrcs[1].id());

        EXPECT_EQ(fake_chrc1, chrcs[0].info());
        EXPECT_EQ(fake_chrc2, chrcs[1].info());
      });

  EXPECT_EQ(0u, fake_client()->chrc_discovery_count());
  RunLoopUntilIdle();

  // Only one ATT request should have been made.
  EXPECT_EQ(1u, fake_client()->chrc_discovery_count());

  EXPECT_TRUE(service->IsDiscovered());
  EXPECT_TRUE(status1);
  EXPECT_TRUE(status2);
  EXPECT_EQ(data.range_start,
            fake_client()->last_chrc_discovery_start_handle());
  EXPECT_EQ(data.range_end, fake_client()->last_chrc_discovery_end_handle());

  // Request discovery again. This should succeed without an ATT request.
  status1 = att::Status(HostError::kFailed);
  service->DiscoverCharacteristics(
      [&status1](att::Status cb_status, const auto&) { status1 = cb_status; });

  RunLoopUntilIdle();

  EXPECT_TRUE(status1);
  EXPECT_EQ(1u, fake_client()->chrc_discovery_count());
  EXPECT_TRUE(service->IsDiscovered());
}

TEST_F(GATT_RemoteServiceManagerTest, DiscoverCharacteristicsError) {
  ServiceData data(1, 5, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chrc1(0, 2, 3, kTestUuid3);
  CharacteristicData chrc2(0, 4, 5, kTestUuid4);
  std::vector<CharacteristicData> fake_chrcs{{chrc1, chrc2}};
  fake_client()->set_characteristics(std::move(fake_chrcs));

  fake_client()->set_characteristic_discovery_status(
      att::Status(HostError::kNotSupported));

  att::Status status1;
  RemoteCharacteristicList chrcs1;
  service->DiscoverCharacteristics(
      [&](att::Status cb_status, const auto& chrcs) {
        status1 = cb_status;
        EXPECT_TRUE(chrcs.empty());
      });

  // Queue a second request.
  att::Status status2;
  RemoteCharacteristicList chrcs2;
  service->DiscoverCharacteristics(
      [&](att::Status cb_status, const auto& chrcs) {
        status2 = cb_status;
        EXPECT_TRUE(chrcs.empty());
      });

  EXPECT_EQ(0u, fake_client()->chrc_discovery_count());
  RunLoopUntilIdle();

  // Onle one request should have been made.
  EXPECT_EQ(1u, fake_client()->chrc_discovery_count());

  EXPECT_FALSE(service->IsDiscovered());
  EXPECT_FALSE(status1);
  EXPECT_FALSE(status2);
  EXPECT_EQ(HostError::kNotSupported, status1.error());
  EXPECT_EQ(HostError::kNotSupported, status2.error());
}

// Discover descriptors of a service with one characteristic.
TEST_F(GATT_RemoteServiceManagerTest, DiscoverDescriptorsOfOneSuccess) {
  constexpr att::Handle kStart = 1;
  constexpr att::Handle kCharDecl = 2;
  constexpr att::Handle kCharValue = 3;
  constexpr att::Handle kDesc1 = 4;
  constexpr att::Handle kDesc2 = 5;
  constexpr att::Handle kEnd = 5;

  ServiceData data(kStart, kEnd, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData fake_chrc(0, kCharDecl, kCharValue, kTestUuid3);
  fake_client()->set_characteristics({{fake_chrc}});

  DescriptorData fake_desc1(kDesc1, kTestUuid3);
  DescriptorData fake_desc2(kDesc2, kTestUuid4);
  fake_client()->set_descriptors({{fake_desc1, fake_desc2}});

  att::Status status(HostError::kFailed);
  service->DiscoverCharacteristics(
      [&](att::Status cb_status, const auto& chrcs) {
        status = cb_status;
        EXPECT_EQ(1u, chrcs.size());

        EXPECT_EQ(2u, chrcs[0].descriptors().size());
        EXPECT_EQ(0u, chrcs[0].descriptors()[0].id());
        EXPECT_EQ(fake_desc1, chrcs[0].descriptors()[0].info());
        EXPECT_EQ(1u, chrcs[0].descriptors()[1].id());
        EXPECT_EQ(fake_desc2, chrcs[0].descriptors()[1].info());
      });

  EXPECT_EQ(0u, fake_client()->chrc_discovery_count());
  RunLoopUntilIdle();

  EXPECT_EQ(1u, fake_client()->chrc_discovery_count());
  EXPECT_EQ(1u, fake_client()->desc_discovery_count());
  EXPECT_TRUE(service->IsDiscovered());
  EXPECT_TRUE(status);
  EXPECT_EQ(kDesc1, fake_client()->last_desc_discovery_start_handle());
  EXPECT_EQ(kEnd, fake_client()->last_desc_discovery_end_handle());
}

// Discover descriptors of a service with one characteristic.
TEST_F(GATT_RemoteServiceManagerTest, DiscoverDescriptorsOfOneError) {
  constexpr att::Handle kStart = 1;
  constexpr att::Handle kCharDecl = 2;
  constexpr att::Handle kCharValue = 3;
  constexpr att::Handle kDesc1 = 4;
  constexpr att::Handle kDesc2 = 5;
  constexpr att::Handle kEnd = 5;

  ServiceData data(kStart, kEnd, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData fake_chrc(0, kCharDecl, kCharValue, kTestUuid3);
  fake_client()->set_characteristics({{fake_chrc}});

  DescriptorData fake_desc1(kDesc1, kTestUuid3);
  DescriptorData fake_desc2(kDesc2, kTestUuid4);
  fake_client()->set_descriptors({{fake_desc1, fake_desc2}});
  fake_client()->set_descriptor_discovery_status(
      att::Status(HostError::kNotSupported));

  att::Status status;
  service->DiscoverCharacteristics(
      [&](att::Status cb_status, const auto& chrcs) {
        status = cb_status;
        EXPECT_TRUE(chrcs.empty());
      });

  EXPECT_EQ(0u, fake_client()->chrc_discovery_count());
  RunLoopUntilIdle();

  EXPECT_EQ(1u, fake_client()->chrc_discovery_count());
  EXPECT_EQ(1u, fake_client()->desc_discovery_count());
  EXPECT_FALSE(service->IsDiscovered());
  EXPECT_FALSE(status);
  EXPECT_EQ(HostError::kNotSupported, status.error());
}

// Discover descriptors of a service with multiple characteristics
TEST_F(GATT_RemoteServiceManagerTest, DiscoverDescriptorsOfMultipleSuccess) {
  // Has one descriptor
  CharacteristicData fake_char1(0, 2, 3, kTestUuid3);
  DescriptorData fake_desc1(4, kTestUuid4);

  // Has no descriptors
  CharacteristicData fake_char2(0, 5, 6, kTestUuid3);

  // Has two descriptors
  CharacteristicData fake_char3(0, 7, 8, kTestUuid3);
  DescriptorData fake_desc2(9, kTestUuid4);
  DescriptorData fake_desc3(10, kTestUuid4);

  ServiceData data(1, fake_desc3.handle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);
  fake_client()->set_characteristics({{fake_char1, fake_char2, fake_char3}});
  fake_client()->set_descriptors({{fake_desc1, fake_desc2, fake_desc3}});

  att::Status status(HostError::kFailed);
  service->DiscoverCharacteristics(
      [&](att::Status cb_status, const auto& chrcs) {
        status = cb_status;
        EXPECT_EQ(3u, chrcs.size());

        // Characteristic #1
        EXPECT_EQ(1u, chrcs[0].descriptors().size());
        EXPECT_EQ(0u, chrcs[0].descriptors()[0].id());
        EXPECT_EQ(fake_desc1, chrcs[0].descriptors()[0].info());

        // Characteristic #2
        EXPECT_TRUE(chrcs[1].descriptors().empty());

        // Characteristic #3
        EXPECT_EQ(2u, chrcs[2].descriptors().size());
        EXPECT_EQ(2u, chrcs[2].id());
        EXPECT_EQ(0x020000u, chrcs[2].descriptors()[0].id());
        EXPECT_EQ(fake_desc2, chrcs[2].descriptors()[0].info());
        EXPECT_EQ(0x020001u, chrcs[2].descriptors()[1].id());
        EXPECT_EQ(fake_desc3, chrcs[2].descriptors()[1].info());
      });

  EXPECT_EQ(0u, fake_client()->chrc_discovery_count());
  RunLoopUntilIdle();

  EXPECT_EQ(1u, fake_client()->chrc_discovery_count());

  // There should have been two descriptor discovery requests as discovery
  // should have been skipped for characteristic #2 due to its handles.
  EXPECT_EQ(2u, fake_client()->desc_discovery_count());
  EXPECT_TRUE(service->IsDiscovered());
  EXPECT_TRUE(status);
}

// Discover descriptors of a service with multiple characteristics. The first
// request results in an error though others succeed.
TEST_F(GATT_RemoteServiceManagerTest, DiscoverDescriptorsOfMultipleEarlyFail) {
  // Has one descriptor
  CharacteristicData fake_char1(0, 2, 3, kTestUuid3);
  DescriptorData fake_desc1(4, kTestUuid4);

  // Has no descriptors
  CharacteristicData fake_char2(0, 5, 6, kTestUuid3);

  // Has two descriptors
  CharacteristicData fake_char3(0, 7, 8, kTestUuid3);
  DescriptorData fake_desc2(9, kTestUuid4);
  DescriptorData fake_desc3(10, kTestUuid4);

  ServiceData data(1, fake_desc3.handle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);
  fake_client()->set_characteristics({{fake_char1, fake_char2, fake_char3}});
  fake_client()->set_descriptors({{fake_desc1, fake_desc2, fake_desc3}});

  // The first request will fail
  fake_client()->set_descriptor_discovery_status(
      att::Status(HostError::kNotSupported), 1);

  att::Status status(HostError::kFailed);
  service->DiscoverCharacteristics(
      [&](att::Status cb_status, const auto& chrcs) {
        status = cb_status;
        EXPECT_TRUE(chrcs.empty());
      });

  EXPECT_EQ(0u, fake_client()->chrc_discovery_count());
  RunLoopUntilIdle();

  EXPECT_EQ(1u, fake_client()->chrc_discovery_count());

  // There should have been two descriptor discovery requests as discovery
  // should have been skipped for characteristic #2 due to its handles.
  EXPECT_EQ(2u, fake_client()->desc_discovery_count());
  EXPECT_FALSE(service->IsDiscovered());
  EXPECT_EQ(HostError::kNotSupported, status.error());
}

// Discover descriptors of a service with multiple characteristics. The last
// request results in an error while the preceding ones succeed.
TEST_F(GATT_RemoteServiceManagerTest, DiscoverDescriptorsOfMultipleLateFail) {
  // Has one descriptor
  CharacteristicData fake_char1(0, 2, 3, kTestUuid3);
  DescriptorData fake_desc1(4, kTestUuid4);

  // Has no descriptors
  CharacteristicData fake_char2(0, 5, 6, kTestUuid3);

  // Has two descriptors
  CharacteristicData fake_char3(0, 7, 8, kTestUuid3);
  DescriptorData fake_desc2(9, kTestUuid4);
  DescriptorData fake_desc3(10, kTestUuid4);

  ServiceData data(1, fake_desc3.handle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);
  fake_client()->set_characteristics({{fake_char1, fake_char2, fake_char3}});
  fake_client()->set_descriptors({{fake_desc1, fake_desc2, fake_desc3}});

  // The last request will fail
  fake_client()->set_descriptor_discovery_status(
      att::Status(HostError::kNotSupported), 2);

  att::Status status(HostError::kFailed);
  service->DiscoverCharacteristics(
      [&](att::Status cb_status, const auto& chrcs) {
        status = cb_status;
        EXPECT_TRUE(chrcs.empty());
      });

  EXPECT_EQ(0u, fake_client()->chrc_discovery_count());
  RunLoopUntilIdle();

  EXPECT_EQ(1u, fake_client()->chrc_discovery_count());

  // There should have been two descriptor discovery requests as discovery
  // should have been skipped for characteristic #2 due to its handles.
  EXPECT_EQ(2u, fake_client()->desc_discovery_count());
  EXPECT_FALSE(service->IsDiscovered());
  EXPECT_EQ(HostError::kNotSupported, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, ReadCharAfterShutDown) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  service->ShutDown();

  att::Status status;
  service->ReadCharacteristic(
      0, [&](att::Status cb_status, const auto&) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kFailed, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, ReadCharWhileNotReady) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  att::Status status;
  service->ReadCharacteristic(
      0, [&](att::Status cb_status, const auto&) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotReady, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, ReadCharNotFound) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);
  SetupCharacteristics(service, std::vector<CharacteristicData>());

  att::Status status;
  service->ReadCharacteristic(
      0, [&](att::Status cb_status, const auto&) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotFound, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, ReadCharNotSupported) {
  ServiceData data(1, 3, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  // No "read" property set.
  CharacteristicData chr(0, 2, 3, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  att::Status status;
  service->ReadCharacteristic(
      0, [&](att::Status cb_status, const auto&) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotSupported, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, ReadCharSendsReadRequest) {
  constexpr att::Handle kValueHandle = 3;

  ServiceData data(1, kValueHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kRead, 2, kValueHandle, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  const auto kValue = CreateStaticByteBuffer('t', 'e', 's', 't');

  fake_client()->set_read_request_callback(
      [&](att::Handle handle, auto callback) {
        EXPECT_EQ(kValueHandle, handle);
        callback(att::Status(), kValue);
      });

  att::Status status(HostError::kFailed);
  service->ReadCharacteristic(0, [&](att::Status cb_status, const auto& value) {
    status = cb_status;
    EXPECT_TRUE(ContainersEqual(kValue, value));
  });

  RunLoopUntilIdle();

  EXPECT_TRUE(status);
}

TEST_F(GATT_RemoteServiceManagerTest, ReadCharSendsReadRequestWithDispatcher) {
  constexpr att::Handle kValueHandle = 3;

  ServiceData data(1, kValueHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kRead, 2, kValueHandle, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  const auto kValue = CreateStaticByteBuffer('t', 'e', 's', 't');

  fake_client()->set_read_request_callback(
      [&](att::Handle handle, auto callback) {
        EXPECT_EQ(kValueHandle, handle);
        callback(att::Status(), kValue);
      });

  att::Status status(HostError::kFailed);
  service->ReadCharacteristic(
      0,
      [&](att::Status cb_status, const auto& value) {
        status = cb_status;
        EXPECT_TRUE(ContainersEqual(kValue, value));
      },
      dispatcher());

  RunLoopUntilIdle();

  EXPECT_TRUE(status);
}

TEST_F(GATT_RemoteServiceManagerTest, ReadLongAfterShutDown) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  service->ShutDown();

  att::Status status;
  service->ReadLongCharacteristic(
      0, 0, 512,
      [&](att::Status cb_status, const auto&) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kFailed, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, ReadLongWhileNotReady) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  att::Status status;
  service->ReadLongCharacteristic(
      0, 0, 512,
      [&](att::Status cb_status, const auto&) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotReady, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, ReadLongNotFound) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);
  SetupCharacteristics(service, std::vector<CharacteristicData>());

  att::Status status;
  service->ReadLongCharacteristic(
      0, 0, 512,
      [&](att::Status cb_status, const auto&) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotFound, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, ReadLongNotSupported) {
  ServiceData data(1, 3, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  // No "read" property set.
  CharacteristicData chr(0, 2, 3, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  att::Status status;
  service->ReadLongCharacteristic(
      0, 0, 512,
      [&](att::Status cb_status, const auto&) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotSupported, status.error());
}

// 0 is not a valid parameter for the |max_size| field of ReadLongCharacteristic
TEST_F(GATT_RemoteServiceManagerTest, ReadLongMaxSizeZero) {
  ServiceData data(1, 3, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kRead, 2, 3, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  att::Status status;
  service->ReadLongCharacteristic(
      0, 0, 0, [&](att::Status cb_status, const auto&) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kInvalidParameters, status.error());
}

// The complete attribute value is read in a single request.
TEST_F(GATT_RemoteServiceManagerTest, ReadLongSingleBlob) {
  constexpr att::Handle kValueHandle = 3;
  constexpr uint16_t kOffset = 0;
  constexpr size_t kMaxBytes = 1000;

  ServiceData data(1, kValueHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kRead, 2, kValueHandle, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  const auto kValue = CreateStaticByteBuffer('t', 'e', 's', 't');

  fake_client()->set_read_blob_request_callback(
      [&](att::Handle handle, uint16_t offset, auto callback) {
        EXPECT_EQ(kValueHandle, handle);
        EXPECT_EQ(kOffset, offset);
        callback(att::Status(), kValue);
      });

  att::Status status(HostError::kFailed);
  service->ReadLongCharacteristic(
      0, kOffset, kMaxBytes, [&](att::Status cb_status, const auto& value) {
        status = cb_status;
        EXPECT_TRUE(ContainersEqual(kValue, value));
      });

  RunLoopUntilIdle();
  EXPECT_TRUE(status);
}

TEST_F(GATT_RemoteServiceManagerTest, ReadLongMultipleBlobs) {
  constexpr att::Handle kValueHandle = 3;
  constexpr uint16_t kOffset = 0;
  constexpr size_t kMaxBytes = 1000;
  constexpr int kExpectedBlobCount = 4;

  ServiceData data(1, kValueHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kRead, 2, kValueHandle, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  // Create a buffer that will take 4 requests to read. Since the default MTU is
  // 23:
  //   a. The size of |expected_value| is 69.
  //   b. We should read 22 + 22 + 22 + 3 bytes across 4 requests.
  StaticByteBuffer<att::kLEMinMTU * 3> expected_value;

  // Initialize the contents.
  for (size_t i = 0; i < expected_value.size(); ++i) {
    expected_value[i] = i;
  }

  int read_blob_count = 0;
  fake_client()->set_read_blob_request_callback(
      [&](att::Handle handle, uint16_t offset, auto callback) {
        EXPECT_EQ(kValueHandle, handle);
        read_blob_count++;

        // Return a blob at the given offset with at most MTU - 1 bytes.
        auto blob = expected_value.view(offset, att::kLEMinMTU - 1);
        if (read_blob_count == kExpectedBlobCount) {
          // The final blob should contain 3 bytes.
          EXPECT_EQ(3u, blob.size());
        }

        callback(att::Status(), blob);
      });

  att::Status status(HostError::kFailed);
  service->ReadLongCharacteristic(
      0, kOffset, kMaxBytes, [&](att::Status cb_status, const auto& value) {
        status = cb_status;
        EXPECT_TRUE(ContainersEqual(expected_value, value));
      });

  RunLoopUntilIdle();
  EXPECT_TRUE(status);
  EXPECT_EQ(kExpectedBlobCount, read_blob_count);
}

// Same as ReadLongMultipleBlobs except the characteristic value has a size that
// is a multiple of (ATT_MTU - 1), so that the last read blob request returns 0
// bytes.
TEST_F(GATT_RemoteServiceManagerTest, ReadLongValueExactMultipleOfMTU) {
  constexpr att::Handle kValueHandle = 3;
  constexpr uint16_t kOffset = 0;
  constexpr size_t kMaxBytes = 1000;
  constexpr int kExpectedBlobCount = 4;

  ServiceData data(1, kValueHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kRead, 2, kValueHandle, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  // Create a buffer that will take 4 requests to read. Since the default MTU is
  // 23:
  //   a. The size of |expected_value| is 66.
  //   b. We should read 22 + 22 + 22 + 0 bytes across 4 requests.
  StaticByteBuffer<(att::kLEMinMTU - 1) * 3> expected_value;

  // Initialize the contents.
  for (size_t i = 0; i < expected_value.size(); ++i) {
    expected_value[i] = i;
  }

  int read_blob_count = 0;
  fake_client()->set_read_blob_request_callback(
      [&](att::Handle handle, uint16_t offset, auto callback) {
        EXPECT_EQ(kValueHandle, handle);
        read_blob_count++;

        // Return a blob at the given offset with at most MTU - 1 bytes.
        auto blob = expected_value.view(offset, att::kLEMinMTU - 1);
        if (read_blob_count == kExpectedBlobCount) {
          // The final blob should be empty.
          EXPECT_EQ(0u, blob.size());
        }

        callback(att::Status(), blob);
      });

  att::Status status(HostError::kFailed);
  service->ReadLongCharacteristic(
      0, kOffset, kMaxBytes, [&](att::Status cb_status, const auto& value) {
        status = cb_status;
        EXPECT_TRUE(ContainersEqual(expected_value, value));
      });

  RunLoopUntilIdle();
  EXPECT_TRUE(status);
  EXPECT_EQ(kExpectedBlobCount, read_blob_count);
}

// Same as ReadLongMultipleBlobs but a maximum size is given that is smaller
// than the size of the attribute value.
TEST_F(GATT_RemoteServiceManagerTest, ReadLongMultipleBlobsWithMaxSize) {
  constexpr att::Handle kValueHandle = 3;
  constexpr uint16_t kOffset = 0;
  constexpr size_t kMaxBytes = 40;
  constexpr int kExpectedBlobCount = 2;

  ServiceData data(1, kValueHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kRead, 2, kValueHandle, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  StaticByteBuffer<att::kLEMinMTU * 3> expected_value;

  // Initialize the contents.
  for (size_t i = 0; i < expected_value.size(); ++i) {
    expected_value[i] = i;
  }

  int read_blob_count = 0;
  fake_client()->set_read_blob_request_callback(
      [&](att::Handle handle, uint16_t offset, auto callback) {
        EXPECT_EQ(kValueHandle, handle);
        read_blob_count++;
        callback(att::Status(),
                 expected_value.view(offset, att::kLEMinMTU - 1));
      });

  att::Status status(HostError::kFailed);
  service->ReadLongCharacteristic(
      0, kOffset, kMaxBytes, [&](att::Status cb_status, const auto& value) {
        status = cb_status;
        EXPECT_TRUE(ContainersEqual(expected_value.view(0, kMaxBytes), value));
      });

  RunLoopUntilIdle();
  EXPECT_TRUE(status);
  EXPECT_EQ(kExpectedBlobCount, read_blob_count);
}

// Same as ReadLongMultipleBlobs but a non-zero offset is given.
TEST_F(GATT_RemoteServiceManagerTest, ReadLongAtOffset) {
  constexpr att::Handle kValueHandle = 3;
  constexpr uint16_t kOffset = 30;
  constexpr size_t kMaxBytes = 1000;
  constexpr int kExpectedBlobCount = 2;

  ServiceData data(1, kValueHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kRead, 2, kValueHandle, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  // Size: 69.
  // Reads starting at offset 30 will return 22 + 17 bytes across 2 requests.
  StaticByteBuffer<att::kLEMinMTU * 3> expected_value;

  // Initialize the contents.
  for (size_t i = 0; i < expected_value.size(); ++i) {
    expected_value[i] = i;
  }

  int read_blob_count = 0;
  fake_client()->set_read_blob_request_callback(
      [&](att::Handle handle, uint16_t offset, auto callback) {
        EXPECT_EQ(kValueHandle, handle);
        read_blob_count++;
        callback(att::Status(),
                 expected_value.view(offset, att::kLEMinMTU - 1));
      });

  att::Status status(HostError::kFailed);
  service->ReadLongCharacteristic(
      0, kOffset, kMaxBytes, [&](att::Status cb_status, const auto& value) {
        status = cb_status;
        EXPECT_TRUE(
            ContainersEqual(expected_value.view(kOffset, kMaxBytes), value));
      });

  RunLoopUntilIdle();
  EXPECT_TRUE(status);
  EXPECT_EQ(kExpectedBlobCount, read_blob_count);
}

// Same as ReadLongAtOffset but a very small max size is given.
TEST_F(GATT_RemoteServiceManagerTest, ReadLongAtOffsetWithMaxBytes) {
  constexpr att::Handle kValueHandle = 3;
  constexpr uint16_t kOffset = 10;
  constexpr size_t kMaxBytes = 34;
  constexpr int kExpectedBlobCount = 2;

  ServiceData data(1, kValueHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kRead, 2, kValueHandle, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  // Size: 69. 4 bytes will be read in a single request starting at index 30.
  // Reads starting at offset 10 will return 12 + 22 bytes across 2 requests. A
  // third read blob should not be sent since this should satisfy |kMaxBytes|.
  StaticByteBuffer<att::kLEMinMTU * 3> expected_value;

  // Initialize the contents.
  for (size_t i = 0; i < expected_value.size(); ++i) {
    expected_value[i] = i;
  }

  int read_blob_count = 0;
  fake_client()->set_read_blob_request_callback(
      [&](att::Handle handle, uint16_t offset, auto callback) {
        EXPECT_EQ(kValueHandle, handle);
        read_blob_count++;
        callback(att::Status(),
                 expected_value.view(offset, att::kLEMinMTU - 1));
      });

  att::Status status(HostError::kFailed);
  service->ReadLongCharacteristic(
      0, kOffset, kMaxBytes, [&](att::Status cb_status, const auto& value) {
        status = cb_status;
        EXPECT_TRUE(
            ContainersEqual(expected_value.view(kOffset, kMaxBytes), value));
      });

  RunLoopUntilIdle();
  EXPECT_TRUE(status);
  EXPECT_EQ(kExpectedBlobCount, read_blob_count);
}

TEST_F(GATT_RemoteServiceManagerTest, ReadLongError) {
  constexpr att::Handle kValueHandle = 3;
  constexpr uint16_t kOffset = 0;
  constexpr size_t kMaxBytes = 1000;
  constexpr int kExpectedBlobCount = 2;  // The second request will fail.

  ServiceData data(1, kValueHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kRead, 2, kValueHandle, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  // Make the first blob large enough that it will cause a second read blob
  // request.
  StaticByteBuffer<att::kLEMinMTU - 1> first_blob;

  int read_blob_count = 0;
  fake_client()->set_read_blob_request_callback(
      [&](att::Handle handle, uint16_t offset, auto callback) {
        EXPECT_EQ(kValueHandle, handle);
        read_blob_count++;
        if (read_blob_count == kExpectedBlobCount) {
          callback(att::Status(att::ErrorCode::kInvalidOffset), BufferView());
        } else {
          callback(att::Status(), first_blob);
        }
      });

  att::Status status;
  service->ReadLongCharacteristic(
      0, kOffset, kMaxBytes, [&](att::Status cb_status, const auto& value) {
        status = cb_status;
        EXPECT_EQ(0u, value.size());  // No value should be returned on error.
      });

  RunLoopUntilIdle();
  EXPECT_EQ(att::ErrorCode::kInvalidOffset, status.protocol_error());
  EXPECT_EQ(kExpectedBlobCount, read_blob_count);
}

// The service is shut down while before the first read blob response. The
// operation should get canceled.
TEST_F(GATT_RemoteServiceManagerTest, ReadLongShutDownWhileInProgress) {
  constexpr att::Handle kValueHandle = 3;
  constexpr uint16_t kOffset = 0;
  constexpr size_t kMaxBytes = 1000;
  constexpr int kExpectedBlobCount = 1;

  ServiceData data(1, kValueHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kRead, 2, kValueHandle, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  StaticByteBuffer<att::kLEMinMTU - 1> first_blob;

  int read_blob_count = 0;
  fake_client()->set_read_blob_request_callback(
      [&](att::Handle handle, uint16_t offset, auto callback) {
        EXPECT_EQ(kValueHandle, handle);
        read_blob_count++;

        service->ShutDown();
        callback(att::Status(), first_blob);
      });

  att::Status status;
  service->ReadLongCharacteristic(
      0, kOffset, kMaxBytes, [&](att::Status cb_status, const auto& value) {
        status = cb_status;
        EXPECT_EQ(0u, value.size());  // No value should be returned on error.
      });

  RunLoopUntilIdle();
  EXPECT_EQ(HostError::kCanceled, status.error());
  EXPECT_EQ(kExpectedBlobCount, read_blob_count);
}

TEST_F(GATT_RemoteServiceManagerTest, WriteCharAfterShutDown) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  service->ShutDown();

  att::Status status;
  service->WriteCharacteristic(
      0, std::vector<uint8_t>(),
      [&](att::Status cb_status) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kFailed, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, WriteCharWhileNotReady) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  att::Status status;
  service->WriteCharacteristic(
      0, std::vector<uint8_t>(),
      [&](att::Status cb_status) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotReady, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, WriteCharNotFound) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);
  SetupCharacteristics(service, std::vector<CharacteristicData>());

  att::Status status;
  service->WriteCharacteristic(
      0, std::vector<uint8_t>(),
      [&](att::Status cb_status) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotFound, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, WriteCharNotSupported) {
  ServiceData data(1, 3, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  // No "write" property set.
  CharacteristicData chr(0, 2, 3, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  att::Status status;
  service->WriteCharacteristic(
      0, std::vector<uint8_t>(),
      [&](att::Status cb_status) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotSupported, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, WriteCharSendsWriteRequest) {
  constexpr att::Handle kValueHandle = 3;
  const std::vector<uint8_t> kValue{{'t', 'e', 's', 't'}};
  constexpr att::Status kStatus(att::ErrorCode::kWriteNotPermitted);

  ServiceData data(1, kValueHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kWrite, 2, kValueHandle, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  fake_client()->set_write_request_callback(
      [&](att::Handle handle, const auto& value, auto status_callback) {
        EXPECT_EQ(kValueHandle, handle);
        EXPECT_TRUE(std::equal(kValue.begin(), kValue.end(), value.begin(),
                               value.end()));
        status_callback(kStatus);
      });

  att::Status status;
  service->WriteCharacteristic(
      0, kValue, [&](att::Status cb_status) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_TRUE(status.is_protocol_error());
  EXPECT_EQ(kStatus, status);
}

TEST_F(GATT_RemoteServiceManagerTest, WriteWithoutResponseNotSupported) {
  ServiceData data(1, 3, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  // No "write without response" property.
  CharacteristicData chr(0, 2, 3, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  bool called = false;
  fake_client()->set_write_without_rsp_callback(
      [&](auto, const auto&) { called = true; });

  service->WriteCharacteristicWithoutResponse(0, std::vector<uint8_t>());
  RunLoopUntilIdle();
  EXPECT_FALSE(called);
}

TEST_F(GATT_RemoteServiceManagerTest, WriteWithoutResponseSuccess) {
  constexpr att::Handle kValueHandle = 3;
  const std::vector<uint8_t> kValue{{'t', 'e', 's', 't'}};

  ServiceData data(1, kValueHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kWriteWithoutResponse, 2, kValueHandle,
                         kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  bool called = false;
  fake_client()->set_write_without_rsp_callback(
      [&](att::Handle handle, const auto& value) {
        EXPECT_EQ(kValueHandle, handle);
        EXPECT_TRUE(std::equal(kValue.begin(), kValue.end(), value.begin(),
                               value.end()));
        called = true;
      });

  service->WriteCharacteristicWithoutResponse(0, kValue);
  RunLoopUntilIdle();

  EXPECT_TRUE(called);
}

TEST_F(GATT_RemoteServiceManagerTest, ReadDescAfterShutDown) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  service->ShutDown();

  att::Status status;
  service->ReadDescriptor(
      0, [&](att::Status cb_status, const auto&) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kFailed, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, ReadDescWhileNotReady) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  att::Status status;
  service->ReadDescriptor(
      0, [&](att::Status cb_status, const auto&) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotReady, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, ReadDescriptorNotFound) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);
  SetupCharacteristics(service, std::vector<CharacteristicData>());

  att::Status status;
  service->ReadDescriptor(
      0, [&](att::Status cb_status, const auto&) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotFound, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, ReadDescSendsReadRequest) {
  // TODO(armansito): Some of the service set up and |status| verification
  // boilerplate could be reduced by factoring them out into helpers on the test
  // harness (also see code review comment in
  // https://fuchsia-review.googlesource.com/c/garnet/+/213794/6/drivers/bluetooth/lib/gatt/remote_service_manager_unittest.cc).
  constexpr att::Handle kValueHandle1 = 3;
  constexpr att::Handle kValueHandle2 = 5;
  constexpr att::Handle kDescrHandle = 6;

  ServiceData data(1, kDescrHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr1(Property::kRead, 2, kValueHandle1, kTestUuid3);
  CharacteristicData chr2(Property::kRead, 4, kValueHandle2, kTestUuid3);
  DescriptorData desc(kDescrHandle, kTestUuid4);
  SetupCharacteristics(service, {{chr1, chr2}}, {{desc}});

  const auto kValue = CreateStaticByteBuffer('t', 'e', 's', 't');

  fake_client()->set_read_request_callback(
      [&](att::Handle handle, auto callback) {
        EXPECT_EQ(kDescrHandle, handle);
        callback(att::Status(), kValue);
      });

  // We read the first descriptor of the second characteristic. The descriptor
  // has this ID based on the scheme described in remote_characteristic.h.
  constexpr IdType kDescrId = 0x010000;
  att::Status status(HostError::kFailed);
  service->ReadDescriptor(kDescrId,
                          [&](att::Status cb_status, const auto& value) {
                            status = cb_status;
                            EXPECT_TRUE(ContainersEqual(kValue, value));
                          });

  RunLoopUntilIdle();

  EXPECT_TRUE(status);
}

TEST_F(GATT_RemoteServiceManagerTest, ReadDescSendsReadRequestWithDispatcher) {
  constexpr att::Handle kValueHandle = 3;
  constexpr att::Handle kDescrHandle = 4;

  ServiceData data(1, kDescrHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kRead, 2, kValueHandle, kTestUuid3);
  DescriptorData desc(kDescrHandle, kTestUuid4);
  SetupCharacteristics(service, {{chr}}, {{desc}});

  const auto kValue = CreateStaticByteBuffer('t', 'e', 's', 't');

  fake_client()->set_read_request_callback(
      [&](att::Handle handle, auto callback) {
        EXPECT_EQ(kDescrHandle, handle);
        callback(att::Status(), kValue);
      });

  att::Status status(HostError::kFailed);
  service->ReadDescriptor(
      0,
      [&](att::Status cb_status, const auto& value) {
        status = cb_status;
        EXPECT_TRUE(ContainersEqual(kValue, value));
      },
      dispatcher());

  RunLoopUntilIdle();

  EXPECT_TRUE(status);
}

TEST_F(GATT_RemoteServiceManagerTest, ReadLongDescWhileNotReady) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  att::Status status;
  service->ReadLongDescriptor(
      0, 0, 512,
      [&](att::Status cb_status, const auto&) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotReady, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, ReadLongDescNotFound) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);
  SetupCharacteristics(service, std::vector<CharacteristicData>());

  att::Status status;
  service->ReadLongDescriptor(
      0, 0, 512,
      [&](att::Status cb_status, const auto&) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotFound, status.error());
}

// Tests that ReadLongDescriptor sends Read Blob requests. Other conditions
// around the long read procedure are already covered by the tests for
// ReadLongCharacteristic as the implementations are shared.
TEST_F(GATT_RemoteServiceManagerTest, ReadLongDescriptor) {
  constexpr att::Handle kValueHandle = 3;
  constexpr att::Handle kDescrHandle = 4;
  constexpr uint16_t kOffset = 0;
  constexpr size_t kMaxBytes = 1000;
  constexpr int kExpectedBlobCount = 4;

  ServiceData data(1, kDescrHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kRead, 2, kValueHandle, kTestUuid3);
  DescriptorData desc(kDescrHandle, kTestUuid4);
  SetupCharacteristics(service, {{chr}}, {{desc}});

  // Create a buffer that will take 4 requests to read. Since the default MTU is
  // 23:
  //   a. The size of |expected_value| is 69.
  //   b. We should read 22 + 22 + 22 + 3 bytes across 4 requests.
  StaticByteBuffer<att::kLEMinMTU * 3> expected_value;

  // Initialize the contents.
  for (size_t i = 0; i < expected_value.size(); ++i) {
    expected_value[i] = i;
  }

  int read_blob_count = 0;
  fake_client()->set_read_blob_request_callback(
      [&](att::Handle handle, uint16_t offset, auto callback) {
        EXPECT_EQ(kDescrHandle, handle);
        read_blob_count++;

        // Return a blob at the given offset with at most MTU - 1 bytes.
        auto blob = expected_value.view(offset, att::kLEMinMTU - 1);
        if (read_blob_count == kExpectedBlobCount) {
          // The final blob should contain 3 bytes.
          EXPECT_EQ(3u, blob.size());
        }

        callback(att::Status(), blob);
      });

  att::Status status(HostError::kFailed);
  service->ReadLongDescriptor(
      0, kOffset, kMaxBytes, [&](att::Status cb_status, const auto& value) {
        status = cb_status;
        EXPECT_TRUE(ContainersEqual(expected_value, value));
      });

  RunLoopUntilIdle();
  EXPECT_TRUE(status);
  EXPECT_EQ(kExpectedBlobCount, read_blob_count);
}

TEST_F(GATT_RemoteServiceManagerTest, WriteDescAfterShutDown) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  service->ShutDown();

  att::Status status;
  service->WriteDescriptor(0, std::vector<uint8_t>(),
                           [&](att::Status cb_status) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kFailed, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, WriteDescWhileNotReady) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  att::Status status;
  service->WriteDescriptor(0, std::vector<uint8_t>(),
                           [&](att::Status cb_status) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotReady, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, WriteDescNotFound) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);
  SetupCharacteristics(service, std::vector<CharacteristicData>());

  att::Status status;
  service->WriteDescriptor(0, std::vector<uint8_t>(),
                           [&](att::Status cb_status) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotFound, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, WriteDescNotAllowed) {
  ServiceData data(1, 4, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  // "CCC" characteristic cannot be written to.
  CharacteristicData chr(0, 2, 3, kTestUuid3);
  DescriptorData desc(4, types::kClientCharacteristicConfig);
  SetupCharacteristics(service, {{chr}}, {{desc}});

  att::Status status;
  service->WriteDescriptor(0, std::vector<uint8_t>(),
                           [&](att::Status cb_status) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotSupported, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, WriteDescSendsWriteRequest) {
  constexpr att::Handle kValueHandle = 3;
  constexpr att::Handle kDescrHandle = 4;
  const std::vector<uint8_t> kValue{{'t', 'e', 's', 't'}};
  const att::Status kStatus(HostError::kNotSupported);

  ServiceData data(1, kValueHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kWrite, 2, kValueHandle, kTestUuid3);
  DescriptorData desc(kDescrHandle, kTestUuid4);
  SetupCharacteristics(service, {{chr}}, {{desc}});

  fake_client()->set_write_request_callback(
      [&](att::Handle handle, const auto& value, auto status_callback) {
        EXPECT_EQ(kValueHandle, handle);
        EXPECT_TRUE(std::equal(kValue.begin(), kValue.end(), value.begin(),
                               value.end()));
        status_callback(kStatus);
      });

  att::Status status;
  service->WriteDescriptor(0, kValue,
                           [&](att::Status cb_status) { status = cb_status; });

  RunLoopUntilIdle();
  EXPECT_EQ(kStatus, status);
}

TEST_F(GATT_RemoteServiceManagerTest, EnableNotificationsAfterShutDown) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  service->ShutDown();

  att::Status status;
  service->EnableNotifications(
      0, NopValueCallback,
      [&](att::Status cb_status, IdType) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kFailed, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, EnableNotificationsWhileNotReady) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  att::Status status;
  service->EnableNotifications(
      0, NopValueCallback,
      [&](att::Status cb_status, IdType) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotReady, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, EnableNotificationsCharNotFound) {
  ServiceData data(1, 2, kTestServiceUuid1);
  auto service = SetUpFakeService(data);
  SetupCharacteristics(service, std::vector<CharacteristicData>());

  att::Status status;
  service->EnableNotifications(
      0, NopValueCallback,
      [&](att::Status cb_status, IdType) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotFound, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, EnableNotificationsNoProperties) {
  ServiceData data(1, 4, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  // Has neither the "notify" nor "indicate" property but has a CCC descriptor.
  CharacteristicData chr(Property::kRead, 2, 3, kTestUuid3);
  DescriptorData desc(4, types::kClientCharacteristicConfig);
  SetupCharacteristics(service, {{chr}}, {{desc}});

  att::Status status;
  service->EnableNotifications(
      0, NopValueCallback,
      [&](att::Status cb_status, IdType) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotSupported, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, EnableNotificationsNoCCC) {
  ServiceData data(1, 3, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  // Has the "notify" property but no CCC descriptor.
  CharacteristicData chr(Property::kNotify, 2, 3, kTestUuid3);
  SetupCharacteristics(service, {{chr}});

  att::Status status;
  service->EnableNotifications(
      0, NopValueCallback,
      [&](att::Status cb_status, IdType) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotSupported, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, EnableNotificationsSuccess) {
  constexpr att::Handle kCCCHandle = 4;

  ServiceData data(1, kCCCHandle, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kNotify, 2, 3, kTestUuid3);
  DescriptorData desc(kCCCHandle, types::kClientCharacteristicConfig);
  SetupCharacteristics(service, {{chr}}, {{desc}});

  fake_client()->set_write_request_callback(
      [&](att::Handle handle, const auto& value, auto status_callback) {
        EXPECT_EQ(kCCCHandle, handle);
        EXPECT_TRUE(ContainersEqual(kCCCNotifyValue, value));
        status_callback(att::Status());
      });

  IdType id = kInvalidId;
  att::Status status(HostError::kFailed);
  service->EnableNotifications(0, NopValueCallback,
                               [&](att::Status cb_status, IdType cb_id) {
                                 status = cb_status;
                                 id = cb_id;
                               });

  RunLoopUntilIdle();

  EXPECT_TRUE(status);
  EXPECT_NE(kInvalidId, id);
}

TEST_F(GATT_RemoteServiceManagerTest, EnableIndications) {
  constexpr att::Handle kCCCHandle = 4;

  ServiceData data(1, 4, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kIndicate, 2, 3, kTestUuid3);
  DescriptorData desc(kCCCHandle, types::kClientCharacteristicConfig);
  SetupCharacteristics(service, {{chr}}, {{desc}});

  fake_client()->set_write_request_callback(
      [&](att::Handle handle, const auto& value, auto status_callback) {
        EXPECT_EQ(kCCCHandle, handle);
        EXPECT_TRUE(ContainersEqual(kCCCIndicateValue, value));
        status_callback(att::Status());
      });

  IdType id = kInvalidId;
  att::Status status(HostError::kFailed);
  service->EnableNotifications(0, NopValueCallback,
                               [&](att::Status cb_status, IdType cb_id) {
                                 status = cb_status;
                                 id = cb_id;
                               });

  RunLoopUntilIdle();

  EXPECT_TRUE(status);
  EXPECT_NE(kInvalidId, id);
}

TEST_F(GATT_RemoteServiceManagerTest, EnableNotificationsError) {
  constexpr att::Handle kCCCHandle = 4;

  ServiceData data(1, 4, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  CharacteristicData chr(Property::kNotify, 2, 3, kTestUuid3);
  DescriptorData desc(kCCCHandle, types::kClientCharacteristicConfig);
  SetupCharacteristics(service, {{chr}}, {{desc}});

  // Should enable notifications
  const auto kExpectedValue = CreateStaticByteBuffer(0x01, 0x00);

  fake_client()->set_write_request_callback(
      [&](att::Handle handle, const auto& value, auto status_callback) {
        EXPECT_EQ(kCCCHandle, handle);
        EXPECT_TRUE(ContainersEqual(kExpectedValue, value));
        status_callback(att::Status(att::ErrorCode::kUnlikelyError));
      });

  IdType id = kInvalidId;
  att::Status status;
  service->EnableNotifications(0, NopValueCallback,
                               [&](att::Status cb_status, IdType cb_id) {
                                 status = cb_status;
                                 id = cb_id;
                               });

  RunLoopUntilIdle();

  EXPECT_TRUE(status.is_protocol_error());
  EXPECT_EQ(att::ErrorCode::kUnlikelyError, status.protocol_error());
  EXPECT_EQ(kInvalidId, id);
}

TEST_F(GATT_RemoteServiceManagerTest, EnableNotificationsRequestMany) {
  constexpr att::Handle kCCCHandle1 = 4;
  constexpr att::Handle kCCCHandle2 = 7;

  ServiceData data(1, 7, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  // Set up two characteristics
  CharacteristicData chr1(Property::kNotify, 2, 3, kTestUuid3);
  DescriptorData desc1(kCCCHandle1, types::kClientCharacteristicConfig);

  CharacteristicData chr2(Property::kIndicate, 5, 6, kTestUuid3);
  DescriptorData desc2(kCCCHandle2, types::kClientCharacteristicConfig);

  SetupCharacteristics(service, {{chr1, chr2}}, {{desc1, desc2}});

  int ccc_write_count = 0;
  att::StatusCallback status_callback1, status_callback2;
  fake_client()->set_write_request_callback(
      [&](att::Handle handle, const auto& value, auto status_cb) {
        if (handle == kCCCHandle1) {
          EXPECT_TRUE(ContainersEqual(kCCCNotifyValue, value));
          status_callback1 = std::move(status_cb);
        } else if (handle == kCCCHandle2) {
          EXPECT_TRUE(ContainersEqual(kCCCIndicateValue, value));
          status_callback2 = std::move(status_cb);
        } else {
          ADD_FAILURE() << "Unexpected handle: " << handle;
        }
        ccc_write_count++;
      });

  size_t cb_count = 0u;

  service->EnableNotifications(0, NopValueCallback,
                               [&](att::Status status, IdType id) {
                                 cb_count++;
                                 EXPECT_EQ(1u, id);
                                 EXPECT_TRUE(status);
                               });
  service->EnableNotifications(0, NopValueCallback,
                               [&](att::Status status, IdType id) {
                                 cb_count++;
                                 EXPECT_EQ(2u, id);
                                 EXPECT_TRUE(status);
                               });
  service->EnableNotifications(1, NopValueCallback,
                               [&](att::Status status, IdType id) {
                                 cb_count++;
                                 EXPECT_EQ(1u, id);
                                 EXPECT_TRUE(status);
                               });
  service->EnableNotifications(1, NopValueCallback,
                               [&](att::Status status, IdType id) {
                                 cb_count++;
                                 EXPECT_EQ(2u, id);
                                 EXPECT_TRUE(status);
                               });
  service->EnableNotifications(1, NopValueCallback,
                               [&](att::Status status, IdType id) {
                                 cb_count++;
                                 EXPECT_EQ(3u, id);
                                 EXPECT_TRUE(status);
                               });

  RunLoopUntilIdle();

  // ATT write requests should be sent but none of the notification requests
  // should be resolved.
  EXPECT_EQ(2, ccc_write_count);
  EXPECT_EQ(0u, cb_count);

  // An ATT response should resolve all pending requests for the right
  // characteristic.
  status_callback1(att::Status());
  EXPECT_EQ(2u, cb_count);
  status_callback2(att::Status());
  EXPECT_EQ(5u, cb_count);

  // An extra request should succeed without sending any PDUs.
  service->EnableNotifications(0, NopValueCallback,
                               [&](att::Status status, IdType) {
                                 cb_count++;
                                 EXPECT_TRUE(status);
                               });

  RunLoopUntilIdle();

  EXPECT_EQ(2, ccc_write_count);
  EXPECT_EQ(6u, cb_count);
}

TEST_F(GATT_RemoteServiceManagerTest, EnableNotificationsRequestManyError) {
  constexpr att::Handle kCCCHandle = 4;

  ServiceData data(1, 4, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  // Set up two characteristics
  CharacteristicData chr(Property::kNotify, 2, 3, kTestUuid3);
  DescriptorData desc(kCCCHandle, types::kClientCharacteristicConfig);

  SetupCharacteristics(service, {{chr}}, {{desc}});

  int ccc_write_count = 0;
  att::StatusCallback status_callback;
  fake_client()->set_write_request_callback(
      [&](att::Handle handle, const auto& value, auto status_cb) {
        EXPECT_EQ(kCCCHandle, handle);
        EXPECT_TRUE(ContainersEqual(kCCCNotifyValue, value));

        ccc_write_count++;
        status_callback = std::move(status_cb);
      });

  int cb_count = 0;
  att::Status status;
  auto cb = [&](att::Status cb_status, IdType id) {
    status = cb_status;
    cb_count++;
  };

  service->EnableNotifications(0, NopValueCallback, std::move(cb));
  service->EnableNotifications(0, NopValueCallback, std::move(cb));
  service->EnableNotifications(0, NopValueCallback, std::move(cb));

  RunLoopUntilIdle();

  // Requests should be buffered and only one ATT request should have been sent
  // out.
  EXPECT_EQ(1, ccc_write_count);
  EXPECT_EQ(0, cb_count);

  status_callback(att::Status(HostError::kNotSupported));
  EXPECT_EQ(3, cb_count);
  EXPECT_EQ(HostError::kNotSupported, status.error());

  // A new request should write to the descriptor again.
  service->EnableNotifications(0, NopValueCallback, std::move(cb));

  RunLoopUntilIdle();

  EXPECT_EQ(2, ccc_write_count);
  EXPECT_EQ(3, cb_count);

  status_callback(att::Status());
  EXPECT_EQ(2, ccc_write_count);
  EXPECT_EQ(4, cb_count);
  EXPECT_TRUE(status);
}

// Notifications received when the remote service database is empty should be
// dropped and not cause a crash.
TEST_F(GATT_RemoteServiceManagerTest, NotificationWithoutServices) {
  for (att::Handle i = 0; i < 10; ++i) {
    fake_client()->SendNotification(
        false, i, CreateStaticByteBuffer('n', 'o', 't', 'i', 'f', 'y'));
  }
  RunLoopUntilIdle();
}

TEST_F(GATT_RemoteServiceManagerTest, NotificationCallback) {
  constexpr IdType kId1 = 0;
  constexpr IdType kId2 = 1;

  ServiceData data(1, 7, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  // Set up two characteristics
  CharacteristicData chr1(Property::kNotify, 2, 3, kTestUuid3);
  DescriptorData desc1(4, types::kClientCharacteristicConfig);

  CharacteristicData chr2(Property::kIndicate, 5, 6, kTestUuid3);
  DescriptorData desc2(7, types::kClientCharacteristicConfig);

  SetupCharacteristics(service, {{chr1, chr2}}, {{desc1, desc2}});

  fake_client()->set_write_request_callback(
      [&](att::Handle, const auto&, auto status_callback) {
        status_callback(att::Status());
      });

  IdType handler_id = kInvalidId;
  att::Status status(HostError::kFailed);

  int chr1_count = 0;
  auto chr1_cb = [&](const ByteBuffer& value) {
    chr1_count++;
    EXPECT_EQ("notify", value.AsString());
  };

  int chr2_count = 0;
  auto chr2_cb = [&](const ByteBuffer& value) {
    chr2_count++;
    EXPECT_EQ("indicate", value.AsString());
  };

  // Notify both characteristics which should get dropped.
  fake_client()->SendNotification(
      false, 3, CreateStaticByteBuffer('n', 'o', 't', 'i', 'f', 'y'));
  fake_client()->SendNotification(
      true, 6, CreateStaticByteBuffer('i', 'n', 'd', 'i', 'c', 'a', 't', 'e'));

  EnableNotifications(service, kId1, &status, &handler_id, std::move(chr1_cb));
  ASSERT_TRUE(status);
  EnableNotifications(service, kId2, &status, &handler_id, std::move(chr2_cb));
  ASSERT_TRUE(status);

  // Notify characteristic 1.
  fake_client()->SendNotification(
      false, 3, CreateStaticByteBuffer('n', 'o', 't', 'i', 'f', 'y'));
  EXPECT_EQ(1, chr1_count);
  EXPECT_EQ(0, chr2_count);

  // Notify characteristic 2.
  fake_client()->SendNotification(
      true, 6, CreateStaticByteBuffer('i', 'n', 'd', 'i', 'c', 'a', 't', 'e'));
  EXPECT_EQ(1, chr1_count);
  EXPECT_EQ(1, chr2_count);

  // Disable notifications from characteristic 1.
  status = att::Status(HostError::kFailed);
  service->DisableNotifications(
      kId1, handler_id, [&](att::Status cb_status) { status = cb_status; });

  RunLoopUntilIdle();
  EXPECT_TRUE(status);

  // Notifications for characteristic 1 should get dropped.
  fake_client()->SendNotification(
      false, 3, CreateStaticByteBuffer('n', 'o', 't', 'i', 'f', 'y'));
  fake_client()->SendNotification(
      true, 6, CreateStaticByteBuffer('i', 'n', 'd', 'i', 'c', 'a', 't', 'e'));
  EXPECT_EQ(1, chr1_count);
  EXPECT_EQ(2, chr2_count);
}

TEST_F(GATT_RemoteServiceManagerTest, DisableNotificationsAfterShutDown) {
  auto service = SetupNotifiableService();

  IdType id = kInvalidId;
  att::Status status(HostError::kFailed);
  EnableNotifications(service, 0, &status, &id);

  EXPECT_TRUE(status);
  EXPECT_NE(kInvalidId, id);

  service->ShutDown();

  service->DisableNotifications(
      0, id, [&](att::Status cb_status) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kFailed, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, DisableNotificationsWhileNotReady) {
  ServiceData data(1, 4, kTestServiceUuid1);
  auto service = SetUpFakeService(data);

  att::Status status;
  service->DisableNotifications(
      0, 1, [&](att::Status cb_status) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotReady, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, DisableNotificationsCharNotFound) {
  auto service = SetupNotifiableService();

  IdType id = kInvalidId;
  att::Status status(HostError::kFailed);
  EnableNotifications(service, 0, &status, &id);

  // "1" is an invalid characteristic ID.
  service->DisableNotifications(
      1, id, [&](att::Status cb_status) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotFound, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, DisableNotificationsIdNotFound) {
  auto service = SetupNotifiableService();

  IdType id = kInvalidId;
  att::Status status(HostError::kFailed);
  EnableNotifications(service, 0, &status, &id);

  // Valid characteristic ID but invalid notification handler ID.
  service->DisableNotifications(
      0, id + 1, [&](att::Status cb_status) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_EQ(HostError::kNotFound, status.error());
}

TEST_F(GATT_RemoteServiceManagerTest, DisableNotificationsSingleHandler) {
  constexpr att::Handle kCCCHandle = 4;
  auto service = SetupNotifiableService();

  IdType id = kInvalidId;
  att::Status status(HostError::kFailed);
  EnableNotifications(service, 0, &status, &id);

  // Should disable notifications
  const auto kExpectedValue = CreateStaticByteBuffer(0x00, 0x00);

  int ccc_write_count = 0;
  fake_client()->set_write_request_callback(
      [&](att::Handle handle, const auto& value, auto status_callback) {
        EXPECT_EQ(kCCCHandle, handle);
        EXPECT_TRUE(ContainersEqual(kExpectedValue, value));
        ccc_write_count++;
        status_callback(att::Status());
      });

  status = att::Status(HostError::kFailed);
  service->DisableNotifications(
      0, id, [&](att::Status cb_status) { status = cb_status; });

  RunLoopUntilIdle();

  EXPECT_TRUE(status);
  EXPECT_EQ(1, ccc_write_count);
}

TEST_F(GATT_RemoteServiceManagerTest, DisableNotificationsDuringShutDown) {
  constexpr att::Handle kCCCHandle = 4;
  auto service = SetupNotifiableService();

  IdType id = kInvalidId;
  att::Status status(HostError::kFailed);
  EnableNotifications(service, 0, &status, &id);
  ASSERT_TRUE(status);

  // Should disable notifications
  const auto kExpectedValue = CreateStaticByteBuffer(0x00, 0x00);

  int ccc_write_count = 0;
  fake_client()->set_write_request_callback(
      [&](att::Handle handle, const auto& value, auto status_callback) {
        EXPECT_EQ(kCCCHandle, handle);
        EXPECT_TRUE(ContainersEqual(kExpectedValue, value));
        ccc_write_count++;
        status_callback(att::Status());
      });

  // Shutting down the service should clear the CCC.
  service->ShutDown();
  RunLoopUntilIdle();

  EXPECT_EQ(1, ccc_write_count);
}

TEST_F(GATT_RemoteServiceManagerTest, DisableNotificationsManyHandlers) {
  auto service = SetupNotifiableService();

  IdType id = kInvalidId;
  std::vector<IdType> handler_ids;

  for (int i = 0; i < 2; i++) {
    att::Status status(HostError::kFailed);
    EnableNotifications(service, 0, &status, &id);
    ASSERT_TRUE(status);
    handler_ids.push_back(id);
  }

  int ccc_write_count = 0;
  fake_client()->set_write_request_callback(
      [&](att::Handle handle, const auto& value, auto status_callback) {
        ccc_write_count++;
        status_callback(att::Status());
      });

  // Disabling should succeed without an ATT transaction.
  att::Status status(HostError::kFailed);
  service->DisableNotifications(
      0, handler_ids.back(),
      [&](att::Status cb_status) { status = cb_status; });
  handler_ids.pop_back();
  RunLoopUntilIdle();
  EXPECT_TRUE(status);
  EXPECT_EQ(0, ccc_write_count);

  // Enabling should succeed without an ATT transaction.
  status = att::Status(HostError::kFailed);
  EnableNotifications(service, 0, &status, &id);
  EXPECT_TRUE(status);
  EXPECT_EQ(0, ccc_write_count);
  handler_ids.push_back(id);

  // Disabling all should send out an ATT transaction.
  while (!handler_ids.empty()) {
    att::Status status(HostError::kFailed);
    service->DisableNotifications(
        0, handler_ids.back(),
        [&](att::Status cb_status) { status = cb_status; });
    handler_ids.pop_back();
    RunLoopUntilIdle();
    EXPECT_TRUE(status);
  }

  EXPECT_EQ(1, ccc_write_count);
}

}  // namespace
}  // namespace internal
}  // namespace gatt
}  // namespace bt
