// Copyright 2020 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 "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/gap/peer.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <pw_async/fake_dispatcher_fixture.h>

#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/advertising_data.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/manufacturer_names.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/hci-spec/util.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/inspect_util.h"

namespace bt::gap {
namespace {

#ifndef NINSPECT
using namespace inspect::testing;
using bt::testing::GetInspectValue;
using bt::testing::ReadInspect;

constexpr uint16_t kManufacturer = 0x0001;
constexpr uint16_t kSubversion = 0x0002;
#endif  // NINSPECT

const StaticByteBuffer kAdvData(0x05,  // Length
                                0x09,  // AD type: Complete Local Name
                                'T',
                                'e',
                                's',
                                't');

const StaticByteBuffer kInvalidAdvData{
    // 32 bit service UUIDs are supposed to be 4 bytes, but the value in this
    // TLV field is only 3
    // bytes long, hence the AdvertisingData is not valid.
    0x04,
    static_cast<uint8_t>(DataType::kComplete32BitServiceUuids),
    0x01,
    0x02,
    0x03,
};

const bt::sm::LTK kLTK;

const DeviceAddress kAddrLePublic(DeviceAddress::Type::kLEPublic,
                                  {1, 2, 3, 4, 5, 6});
const DeviceAddress kAddrLeRandom(DeviceAddress::Type::kLERandom,
                                  {1, 2, 3, 4, 5, 6});
const DeviceAddress kAddrBrEdr(DeviceAddress::Type::kBREDR,
                               {0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA});
// LE Public Device Address that has the same value as a BR/EDR BD_ADDR, e.g. on
// a dual-mode device.
const DeviceAddress kAddrLeAlias(DeviceAddress::Type::kLEPublic,
                                 {0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA});

const bt::sm::LTK kSecureBrEdrKey(
    sm::SecurityProperties(/*encrypted=*/true,
                           /*authenticated=*/true,
                           /*secure_connections=*/true,
                           sm::kMaxEncryptionKeySize),
    hci_spec::LinkKey(UInt128{4}, 5, 6));

class PeerTest : public pw::async::test::FakeDispatcherFixture {
 public:
  PeerTest() = default;

  void SetUp() override {
    // Set up a default peer.
    SetUpPeer(/*address=*/kAddrLePublic, /*connectable=*/true);
  }

  void TearDown() override { peer_.reset(); }

 protected:
  // Can be used to override or reset the default peer. Resets metrics to
  // prevent interference between peers (e.g. by metrics updated in
  // construction).
  void SetUpPeer(const DeviceAddress& address, bool connectable) {
    address_ = address;
    peer_ = std::make_unique<Peer>(
        fit::bind_member<&PeerTest::NotifyListenersCallback>(this),
        fit::bind_member<&PeerTest::UpdateExpiryCallback>(this),
        fit::bind_member<&PeerTest::DualModeCallback>(this),
        fit::bind_member<&PeerTest::StoreLowEnergyBondCallback>(this),
        PeerId(1),
        address_,
        connectable,
        &metrics_,
        dispatcher());
    peer_->AttachInspect(peer_inspector_.GetRoot());
    // Reset metrics as they should only apply to the new peer under test.
    metrics_.AttachInspect(metrics_inspector_.GetRoot());
  }
  Peer& peer() { return *peer_; }

#ifndef NINSPECT
  inspect::Hierarchy ReadPeerInspect() { return ReadInspect(peer_inspector_); }

  std::string InspectLowEnergyConnectionState() {
    std::optional<std::string> val =
        GetInspectValue<inspect::StringPropertyValue>(
            peer_inspector_,
            {"peer",
             "le_data",
             Peer::LowEnergyData::kInspectConnectionStateName});
    BT_ASSERT(val);
    return *val;
  }

  int64_t InspectAdvertisingDataParseFailureCount() {
    std::optional<int64_t> val = GetInspectValue<inspect::IntPropertyValue>(
        peer_inspector_,
        {"peer",
         "le_data",
         Peer::LowEnergyData::kInspectAdvertisingDataParseFailureCountName});
    BT_ASSERT(val);
    return *val;
  }

  std::string InspectLastAdvertisingDataParseFailure() {
    std::optional<std::string> val =
        GetInspectValue<inspect::StringPropertyValue>(
            peer_inspector_,
            {"peer",
             "le_data",
             Peer::LowEnergyData::kInspectLastAdvertisingDataParseFailureName});
    BT_ASSERT(val);
    return *val;
  }

  uint64_t MetricsLowEnergyConnections() {
    std::optional<uint64_t> val = GetInspectValue<inspect::UintPropertyValue>(
        metrics_inspector_, {"metrics", "le", "connection_events"});
    BT_ASSERT(val);
    return *val;
  }

  uint64_t MetricsLowEnergyDisconnections() {
    std::optional<uint64_t> val = GetInspectValue<inspect::UintPropertyValue>(
        metrics_inspector_, {"metrics", "le", "disconnection_events"});
    BT_ASSERT(val);
    return *val;
  }

  std::string InspectBrEdrConnectionState() {
    std::optional<std::string> val =
        GetInspectValue<inspect::StringPropertyValue>(
            peer_inspector_,
            {"peer",
             "bredr_data",
             Peer::BrEdrData::kInspectConnectionStateName});
    BT_ASSERT(val);
    return *val;
  }

  uint64_t MetricsBrEdrConnections() {
    std::optional<uint64_t> val = GetInspectValue<inspect::UintPropertyValue>(
        metrics_inspector_, {"metrics", "bredr", "connection_events"});
    BT_ASSERT(val);
    return *val;
  }

  uint64_t MetricsBrEdrDisconnections() {
    std::optional<uint64_t> val = GetInspectValue<inspect::UintPropertyValue>(
        metrics_inspector_, {"metrics", "bredr", "disconnection_events"});
    BT_ASSERT(val);
    return *val;
  }
#endif  // NINSPECT

  void set_notify_listeners_cb(Peer::NotifyListenersCallback cb) {
    notify_listeners_cb_ = std::move(cb);
  }
  void set_update_expiry_cb(Peer::PeerCallback cb) {
    update_expiry_cb_ = std::move(cb);
  }
  void set_dual_mode_cb(Peer::PeerCallback cb) {
    dual_mode_cb_ = std::move(cb);
  }
  void set_store_le_bond_cb(Peer::StoreLowEnergyBondCallback cb) {
    store_le_bond_cb_ = std::move(cb);
  }

 private:
  void NotifyListenersCallback(const Peer& peer,
                               Peer::NotifyListenersChange change) {
    if (notify_listeners_cb_) {
      notify_listeners_cb_(peer, change);
    }
  }

  void UpdateExpiryCallback(const Peer& peer) {
    if (update_expiry_cb_) {
      update_expiry_cb_(peer);
    }
  }

  void DualModeCallback(const Peer& peer) {
    if (dual_mode_cb_) {
      dual_mode_cb_(peer);
    }
  }

  bool StoreLowEnergyBondCallback(const sm::PairingData& data) {
    if (store_le_bond_cb_) {
      return store_le_bond_cb_(data);
    }
    return false;
  }

  std::unique_ptr<Peer> peer_;
  DeviceAddress address_;
  Peer::NotifyListenersCallback notify_listeners_cb_;
  Peer::PeerCallback update_expiry_cb_;
  Peer::PeerCallback dual_mode_cb_;
  Peer::StoreLowEnergyBondCallback store_le_bond_cb_;
  inspect::Inspector metrics_inspector_;
  PeerMetrics metrics_;
  inspect::Inspector peer_inspector_;
};

class PeerDeathTest : public PeerTest {};

#ifndef NINSPECT
TEST_F(PeerTest, InspectHierarchy) {
  peer().set_version(pw::bluetooth::emboss::CoreSpecificationVersion::V5_0,
                     kManufacturer,
                     kSubversion);

  peer().RegisterName("Sapphire💖", Peer::NameSource::kGenericAccessService);

  peer().MutLe();
  ASSERT_TRUE(peer().le().has_value());

  peer().MutLe().SetFeatures(hci_spec::LESupportedFeatures{0x0000000000000001});

  peer().MutBrEdr().AddService(UUID(uint16_t{0x110b}));

  auto bredr_data_matcher = AllOf(NodeMatches(
      AllOf(NameMatches(Peer::BrEdrData::kInspectNodeName),
            PropertyList(UnorderedElementsAre(
                StringIs(Peer::BrEdrData::kInspectConnectionStateName,
                         Peer::ConnectionStateToString(
                             peer().bredr()->connection_state())),
                StringIs(Peer::BrEdrData::kInspectServicesName,
                         "{ 0000110b-0000-1000-8000-00805f9b34fb }"))))));

  auto le_data_matcher = AllOf(NodeMatches(AllOf(
      NameMatches(Peer::LowEnergyData::kInspectNodeName),
      PropertyList(UnorderedElementsAre(
          StringIs(
              Peer::LowEnergyData::kInspectConnectionStateName,
              Peer::ConnectionStateToString(peer().le()->connection_state())),
          IntIs(
              Peer::LowEnergyData::kInspectAdvertisingDataParseFailureCountName,
              0),
          StringIs(
              Peer::LowEnergyData::kInspectLastAdvertisingDataParseFailureName,
              ""),
          BoolIs(Peer::LowEnergyData::kInspectBondDataName,
                 peer().le()->bonded()),
          StringIs(Peer::LowEnergyData::kInspectFeaturesName,
                   "0x0000000000000001"))))));

  auto peer_matcher = AllOf(
      NodeMatches(PropertyList(UnorderedElementsAre(
          StringIs(Peer::kInspectPeerIdName, peer().identifier().ToString()),
          StringIs(Peer::kInspectPeerNameName,
                   peer().name().value() + " [source: " +
                       Peer::NameSourceToString(
                           Peer::NameSource::kGenericAccessService) +
                       "]"),
          StringIs(Peer::kInspectTechnologyName,
                   TechnologyTypeToString(peer().technology())),
          StringIs(Peer::kInspectAddressName, peer().address().ToString()),
          BoolIs(Peer::kInspectConnectableName, peer().connectable()),
          BoolIs(Peer::kInspectTemporaryName, peer().temporary()),
          StringIs(Peer::kInspectFeaturesName, peer().features().ToString()),
          StringIs(Peer::kInspectVersionName,
                   hci_spec::HCIVersionToString(peer().version().value())),
          StringIs(Peer::kInspectManufacturerName,
                   GetManufacturerName(kManufacturer))))),
      ChildrenMatch(UnorderedElementsAre(bredr_data_matcher, le_data_matcher)));
  // clang-format on
  inspect::Hierarchy hierarchy = ReadPeerInspect();
  EXPECT_THAT(hierarchy,
              AllOf(ChildrenMatch(UnorderedElementsAre(peer_matcher))));
}
#endif  // NINSPECT

#ifndef NINSPECT
TEST_F(PeerTest, SetBrEdrBondDataUpdatesInspectProperties) {
  const char* const kInspectLevelPropertyName = "level";
  const char* const kInspectEncryptedPropertyName = "encrypted";
  const char* const kInspectSecureConnectionsPropertyName =
      "secure_connections";
  const char* const kInspectAuthenticatedPropertyName = "authenticated";
  const char* const kInspectKeyTypePropertyName = "key_type";

  peer().set_version(pw::bluetooth::emboss::CoreSpecificationVersion::V5_0,
                     kManufacturer,
                     kSubversion);

  peer().RegisterName("Sapphire💖", Peer::NameSource::kGenericAccessService);

  peer().MutLe();
  ASSERT_TRUE(peer().le().has_value());

  peer().MutLe().SetFeatures(hci_spec::LESupportedFeatures{0x0000000000000001});

  peer().MutBrEdr().AddService(UUID(uint16_t{0x110b}));
  peer().MutBrEdr().SetBondData(kLTK);

  // clang-format off
  auto bredr_data_matcher = AllOf(
    NodeMatches(AllOf(
      NameMatches(Peer::BrEdrData::kInspectNodeName),
      PropertyList(UnorderedElementsAre(
        StringIs(Peer::BrEdrData::kInspectConnectionStateName,
                 Peer::ConnectionStateToString(peer().bredr()->connection_state())),
        StringIs(Peer::BrEdrData::kInspectServicesName, "{ 0000110b-0000-1000-8000-00805f9b34fb }")
        )))));

  auto le_data_matcher = AllOf(
    NodeMatches(AllOf(
      NameMatches(Peer::LowEnergyData::kInspectNodeName),
      PropertyList(UnorderedElementsAre(
        StringIs(Peer::LowEnergyData::kInspectConnectionStateName,
                 Peer::ConnectionStateToString(peer().le()->connection_state())),
        IntIs(Peer::LowEnergyData::kInspectAdvertisingDataParseFailureCountName, 0),
        StringIs(Peer::LowEnergyData::kInspectLastAdvertisingDataParseFailureName, ""),
        BoolIs(Peer::LowEnergyData::kInspectBondDataName, peer().le()->bonded()),
        StringIs(Peer::LowEnergyData::kInspectFeaturesName, "0x0000000000000001")
        )))));

  auto peer_matcher = AllOf(
    NodeMatches(
      PropertyList(UnorderedElementsAre(
        StringIs(Peer::kInspectPeerIdName, peer().identifier().ToString()),
        StringIs(Peer::kInspectPeerNameName, peer().name().value() + " [source: " + Peer::NameSourceToString(Peer::NameSource::kGenericAccessService) + "]"),
        StringIs(Peer::kInspectTechnologyName, TechnologyTypeToString(peer().technology())),
        StringIs(Peer::kInspectAddressName, peer().address().ToString()),
        BoolIs(Peer::kInspectConnectableName, peer().connectable()),
        BoolIs(Peer::kInspectTemporaryName, peer().temporary()),
        StringIs(Peer::kInspectFeaturesName, peer().features().ToString()),
        StringIs(Peer::kInspectVersionName, hci_spec::HCIVersionToString(peer().version().value())),
        StringIs(Peer::kInspectManufacturerName, GetManufacturerName(kManufacturer))
        ))),
    ChildrenMatch(UnorderedElementsAre(bredr_data_matcher, le_data_matcher)));
  // clang-format on
  inspect::Hierarchy hierarchy = ReadPeerInspect();
  EXPECT_THAT(hierarchy,
              AllOf(ChildrenMatch(UnorderedElementsAre(peer_matcher))));

  peer().MutBrEdr().SetBondData(kSecureBrEdrKey);

  const sm::SecurityProperties security_properties =
      peer().bredr()->link_key().value().security();
  auto link_key_matcher = AllOf(NodeMatches(AllOf(
      NameMatches("link_key"),
      PropertyList(UnorderedElementsAre(
          StringIs(kInspectLevelPropertyName,
                   LevelToString(security_properties.level())),
          BoolIs(kInspectEncryptedPropertyName,
                 security_properties.encrypted()),
          BoolIs(kInspectSecureConnectionsPropertyName,
                 security_properties.secure_connections()),
          BoolIs(kInspectAuthenticatedPropertyName,
                 security_properties.authenticated()),
          StringIs(kInspectKeyTypePropertyName,
                   hci_spec::LinkKeyTypeToString(
                       security_properties.GetLinkKeyType().value())))))));

  auto bredr_data_matcher2 =
      AllOf(NodeMatches(AllOf(
                NameMatches(Peer::BrEdrData::kInspectNodeName),
                PropertyList(UnorderedElementsAre(
                    StringIs(Peer::BrEdrData::kInspectConnectionStateName,
                             Peer::ConnectionStateToString(
                                 peer().bredr()->connection_state())),
                    StringIs(Peer::BrEdrData::kInspectServicesName,
                             "{ 0000110b-0000-1000-8000-00805f9b34fb }"))))),
            ChildrenMatch(UnorderedElementsAre(link_key_matcher)));

  auto le_data_matcher2 = AllOf(NodeMatches(AllOf(
      NameMatches(Peer::LowEnergyData::kInspectNodeName),
      PropertyList(UnorderedElementsAre(
          StringIs(
              Peer::LowEnergyData::kInspectConnectionStateName,
              Peer::ConnectionStateToString(peer().le()->connection_state())),
          IntIs(
              Peer::LowEnergyData::kInspectAdvertisingDataParseFailureCountName,
              0),
          StringIs(
              Peer::LowEnergyData::kInspectLastAdvertisingDataParseFailureName,
              ""),
          BoolIs(Peer::LowEnergyData::kInspectBondDataName,
                 peer().le()->bonded()),
          StringIs(Peer::LowEnergyData::kInspectFeaturesName,
                   "0x0000000000000001"))))));

  auto peer_matcher2 = AllOf(
      NodeMatches(PropertyList(UnorderedElementsAre(
          StringIs(Peer::kInspectPeerIdName, peer().identifier().ToString()),
          StringIs(Peer::kInspectPeerNameName,
                   peer().name().value() + " [source: " +
                       Peer::NameSourceToString(
                           Peer::NameSource::kGenericAccessService) +
                       "]"),
          StringIs(Peer::kInspectTechnologyName,
                   TechnologyTypeToString(peer().technology())),
          StringIs(Peer::kInspectAddressName, peer().address().ToString()),
          BoolIs(Peer::kInspectConnectableName, peer().connectable()),
          BoolIs(Peer::kInspectTemporaryName, peer().temporary()),
          StringIs(Peer::kInspectFeaturesName, peer().features().ToString()),
          StringIs(Peer::kInspectVersionName,
                   hci_spec::HCIVersionToString(peer().version().value())),
          StringIs(Peer::kInspectManufacturerName,
                   GetManufacturerName(kManufacturer))))),
      ChildrenMatch(
          UnorderedElementsAre(bredr_data_matcher2, le_data_matcher2)));
  // clang-format on
  hierarchy = ReadPeerInspect();
  EXPECT_THAT(hierarchy,
              AllOf(ChildrenMatch(UnorderedElementsAre(peer_matcher2))));
}
#endif  // NINSPECT

TEST_F(PeerTest, BrEdrDataAddServiceNotifiesListeners) {
  // Initialize BrEdrData.
  peer().MutBrEdr();
  ASSERT_TRUE(peer().bredr()->services().empty());

  bool listener_notified = false;
  set_notify_listeners_cb([&](auto&, Peer::NotifyListenersChange change) {
    listener_notified = true;
    // Non-bonded peer should not update bond
    EXPECT_EQ(Peer::NotifyListenersChange::kBondNotUpdated, change);
  });

  constexpr UUID kServiceUuid;
  peer().MutBrEdr().AddService(kServiceUuid);
  EXPECT_TRUE(listener_notified);
  EXPECT_EQ(1u, peer().bredr()->services().count(kServiceUuid));

  // De-duplicate subsequent additions of the same service.
  listener_notified = false;
  peer().MutBrEdr().AddService(kServiceUuid);
  EXPECT_FALSE(listener_notified);
}

TEST_F(PeerTest, BrEdrDataAddServiceOnBondedPeerNotifiesListenersToUpdateBond) {
  // Initialize BrEdrData.
  peer().MutBrEdr().SetBondData({});
  ASSERT_TRUE(peer().bredr()->services().empty());

  bool listener_notified = false;
  set_notify_listeners_cb([&](auto&, Peer::NotifyListenersChange change) {
    listener_notified = true;
    // Bonded peer should update bond
    EXPECT_EQ(Peer::NotifyListenersChange::kBondUpdated, change);
  });

  peer().MutBrEdr().AddService(UUID());
  EXPECT_TRUE(listener_notified);
}

TEST_F(PeerTest,
       LowEnergyDataSetAdvDataWithInvalidUtf8NameDoesNotUpdatePeerName) {
  peer().MutLe();  // Initialize LowEnergyData.
  ASSERT_FALSE(peer().name().has_value());

  bool listener_notified = false;
  set_notify_listeners_cb(
      [&](auto&, Peer::NotifyListenersChange) { listener_notified = true; });

  const StaticByteBuffer kAdvData(
      0x05,  // Length
      0x09,  // AD type: Complete Local Name
      'T',
      'e',
      's',
      0xFF  // 0xFF should not appear in a valid UTF-8 string
  );

  peer().MutLe().SetAdvertisingData(
      /*rssi=*/0, kAdvData, pw::chrono::SystemClock::time_point());
  EXPECT_TRUE(listener_notified);  // Fresh AD still results in an update
  EXPECT_FALSE(peer().name().has_value());
}

TEST_F(PeerTest, BrEdrDataSetEirDataWithInvalidUtf8NameDoesNotUpdatePeerName) {
  peer().MutBrEdr();  // Initialize BrEdrData.
  ASSERT_FALSE(peer().name().has_value());

  bool listener_notified = false;
  set_notify_listeners_cb(
      [&](auto&, Peer::NotifyListenersChange) { listener_notified = true; });

  const StaticByteBuffer kEirData(
      0x05,  // Length
      0x09,  // AD type: Complete Local Name
      'T',
      'e',
      's',
      0xFF  // 0xFF should not appear in a valid UTF-8 string
  );

  StaticPacket<pw::bluetooth::emboss::ExtendedInquiryResultEventWriter> eirep;
  eirep.view().num_responses().Write(1);
  eirep.view().bd_addr().CopyFrom(peer().address().value().view());
  eirep.view().extended_inquiry_response().BackingStorage().CopyFrom(
      ::emboss::support::ReadOnlyContiguousBuffer(&kEirData), kEirData.size());

  peer().MutBrEdr().SetInquiryData(eirep.view());
  EXPECT_TRUE(listener_notified);  // Fresh EIR data still results in an update
  EXPECT_FALSE(peer().name().has_value());
}

TEST_F(PeerTest, RegisterNameWithInvalidUtf8NameDoesNotUpdatePeerName) {
  ASSERT_FALSE(peer().name().has_value());

  bool listener_notified = false;
  set_notify_listeners_cb(
      [&](auto&, Peer::NotifyListenersChange) { listener_notified = true; });

  const std::string kName =
      "Tes\xFF\x01";  // 0xFF should not appear in a valid UTF-8 string
  peer().RegisterName(kName);
  EXPECT_FALSE(listener_notified);
  EXPECT_FALSE(peer().name().has_value());
}

TEST_F(PeerTest, LowEnergyAdvertisingDataTimestamp) {
  EXPECT_FALSE(peer().MutLe().parsed_advertising_data_timestamp());
  peer().MutLe().SetAdvertisingData(
      /*rssi=*/0,
      kAdvData,
      pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(1)));
  ASSERT_TRUE(peer().MutLe().parsed_advertising_data_timestamp());
  EXPECT_EQ(peer().MutLe().parsed_advertising_data_timestamp().value(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(1)));

  peer().MutLe().SetAdvertisingData(
      /*rssi=*/0,
      kAdvData,
      pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
  ASSERT_TRUE(peer().MutLe().parsed_advertising_data_timestamp());
  EXPECT_EQ(peer().MutLe().parsed_advertising_data_timestamp().value(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));

  // SetAdvertisingData with data that fails to parse should not update the
  // advertising data timestamp.
  peer().MutLe().SetAdvertisingData(
      /*rssi=*/0,
      kInvalidAdvData,
      pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(3)));
  ASSERT_TRUE(peer().MutLe().parsed_advertising_data_timestamp());
  EXPECT_EQ(peer().MutLe().parsed_advertising_data_timestamp().value(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
}

TEST_F(PeerTest, SettingLowEnergyAdvertisingDataUpdatesLastUpdated) {
  EXPECT_EQ(peer().last_updated(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));

  int notify_count = 0;
  set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
    EXPECT_EQ(peer().last_updated(),
              pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
    notify_count++;
  });

  RunFor(pw::chrono::SystemClock::duration(2));
  peer().MutLe().SetAdvertisingData(
      /*rssi=*/0,
      kAdvData,
      pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(1)));
  EXPECT_EQ(peer().last_updated(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
  EXPECT_GE(notify_count, 1);
}

TEST_F(PeerTest, RegisteringLowEnergyInitializingConnectionUpdatesLastUpdated) {
  EXPECT_EQ(peer().last_updated(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));

  int notify_count = 0;
  set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
    EXPECT_EQ(peer().last_updated(),
              pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
    notify_count++;
  });

  RunFor(pw::chrono::SystemClock::duration(2));
  Peer::InitializingConnectionToken token =
      peer().MutLe().RegisterInitializingConnection();
  EXPECT_EQ(peer().last_updated(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
  EXPECT_GE(notify_count, 1);
}

TEST_F(PeerTest, SettingLowEnergyBondDataUpdatesLastUpdated) {
  EXPECT_EQ(peer().last_updated(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));

  int notify_count = 0;
  set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
    EXPECT_EQ(peer().last_updated(),
              pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
    notify_count++;
  });

  RunFor(pw::chrono::SystemClock::duration(2));
  sm::PairingData data;
  data.peer_ltk = kLTK;
  data.local_ltk = kLTK;
  peer().MutLe().SetBondData(data);
  EXPECT_EQ(peer().last_updated(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
  EXPECT_GE(notify_count, 1);
}

TEST_F(PeerTest, RegisteringBrEdrInitializingConnectionUpdatesLastUpdated) {
  EXPECT_EQ(peer().last_updated(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));

  int notify_count = 0;
  set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
    EXPECT_EQ(peer().last_updated(),
              pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
    notify_count++;
  });

  RunFor(pw::chrono::SystemClock::duration(2));
  Peer::InitializingConnectionToken token =
      peer().MutBrEdr().RegisterInitializingConnection();
  EXPECT_EQ(peer().last_updated(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
  EXPECT_GE(notify_count, 1);
}

TEST_F(PeerTest, SettingInquiryDataUpdatesLastUpdated) {
  SetUpPeer(/*address=*/kAddrLeAlias, /*connectable=*/true);
  EXPECT_EQ(peer().last_updated(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));

  int notify_count = 0;
  set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
    EXPECT_EQ(peer().last_updated(),
              pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
    notify_count++;
  });

  RunFor(pw::chrono::SystemClock::duration(2));
  StaticPacket<pw::bluetooth::emboss::InquiryResultWriter> ir;
  ir.view().bd_addr().CopyFrom(kAddrLeAlias.value().view());
  peer().MutBrEdr().SetInquiryData(ir.view());
  EXPECT_EQ(peer().last_updated(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
  EXPECT_GE(notify_count, 1);
}

TEST_F(PeerTest, SettingBrEdrBondDataUpdatesLastUpdated) {
  EXPECT_EQ(peer().last_updated(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));

  int notify_count = 0;
  set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
    EXPECT_EQ(peer().last_updated(),
              pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
    notify_count++;
  });

  RunFor(pw::chrono::SystemClock::duration(2));
  peer().MutBrEdr().SetBondData(kSecureBrEdrKey);
  EXPECT_EQ(peer().last_updated(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
  EXPECT_GE(notify_count, 1);
}

TEST_F(PeerTest, SettingAddingBrEdrServiceUpdatesLastUpdated) {
  EXPECT_EQ(peer().last_updated(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));

  int notify_count = 0;
  set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
    EXPECT_EQ(peer().last_updated(),
              pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
    notify_count++;
  });

  RunFor(pw::chrono::SystemClock::duration(2));
  peer().MutBrEdr().AddService(UUID(uint16_t{0x110b}));
  EXPECT_EQ(peer().last_updated(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
  EXPECT_GE(notify_count, 1);
}

TEST_F(PeerTest, RegisteringNameUpdatesLastUpdated) {
  EXPECT_EQ(peer().last_updated(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));

  int notify_count = 0;
  set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
    EXPECT_EQ(peer().last_updated(),
              pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
    notify_count++;
  });

  RunFor(pw::chrono::SystemClock::duration(2));
  peer().RegisterName("name");
  EXPECT_EQ(peer().last_updated(),
            pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
  EXPECT_GE(notify_count, 1);
}

TEST_F(PeerTest, RegisterAndUnregisterTwoLowEnergyConnections) {
  SetUpPeer(/*address=*/kAddrLeRandom, /*connectable=*/true);

  int update_expiry_count = 0;
  set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
  int notify_count = 0;
  set_notify_listeners_cb(
      [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });

  std::optional<Peer::ConnectionToken> token_0 =
      peer().MutLe().RegisterConnection();
  // A notification and expiry update are sent when the peer becomes
  // non-temporary, and a second notification and update expiry are sent because
  // the connection is registered.
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 2);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
#ifndef NINSPECT
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
  EXPECT_EQ(MetricsLowEnergyConnections(), 1u);
#endif  // NINSPECT

  std::optional<Peer::ConnectionToken> token_1 =
      peer().MutLe().RegisterConnection();
  // The second connection should not update expiry or notify.
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 2);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
#ifndef NINSPECT
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
  // Although the second connection does not change the high-level connection
  // state, we track it in metrics to support multiple connections to the same
  // peer.
  EXPECT_EQ(MetricsLowEnergyConnections(), 2u);
  EXPECT_EQ(MetricsLowEnergyDisconnections(), 0u);
#endif  // NINSPECT

  token_0.reset();
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 2);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
#ifndef NINSPECT
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
  EXPECT_EQ(MetricsLowEnergyDisconnections(), 1u);
#endif  // NINSPECT

  token_1.reset();
  EXPECT_EQ(update_expiry_count, 3);
  EXPECT_EQ(notify_count, 3);
  EXPECT_TRUE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(),
            Peer::ConnectionState::kNotConnected);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectLowEnergyConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
  EXPECT_EQ(MetricsLowEnergyDisconnections(), 2u);
#endif  // NINSPECT
}

TEST_F(PeerTest, RegisterAndUnregisterLowEnergyConnectionsWhenIdentityKnown) {
  EXPECT_TRUE(peer().identity_known());
  std::optional<Peer::ConnectionToken> token =
      peer().MutLe().RegisterConnection();
  EXPECT_FALSE(peer().temporary());
  token.reset();
  // The peer's identity is known, so it should stay non-temporary upon
  // disconnection.
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(),
            Peer::ConnectionState::kNotConnected);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectLowEnergyConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
#endif  // NINSPECT
}

TEST_F(PeerTest,
       RegisterAndUnregisterInitializingLowEnergyConnectionsWhenIdentityKnown) {
  EXPECT_TRUE(peer().identity_known());
  std::optional<Peer::InitializingConnectionToken> token =
      peer().MutLe().RegisterInitializingConnection();
  EXPECT_FALSE(peer().temporary());
  token.reset();
  // The peer's identity is known, so it should stay non-temporary upon
  // disconnection.
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(),
            Peer::ConnectionState::kNotConnected);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectLowEnergyConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
#endif  // NINSPECT
}

TEST_F(PeerTest,
       RegisterAndUnregisterLowEnergyConnectionDuringInitializingConnection) {
  SetUpPeer(/*address=*/kAddrLeRandom, /*connectable=*/true);

  int update_expiry_count = 0;
  set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
  int notify_count = 0;
  set_notify_listeners_cb(
      [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });

  std::optional<Peer::InitializingConnectionToken> init_token =
      peer().MutLe().RegisterInitializingConnection();
  // A notification and expiry update are sent when the peer becomes
  // non-temporary, and a second notification and update expiry are sent because
  // the initializing connection is registered.
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 2);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(),
            Peer::ConnectionState::kInitializing);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectLowEnergyConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
#endif  // NINSPECT

  std::optional<Peer::ConnectionToken> conn_token =
      peer().MutLe().RegisterConnection();
  EXPECT_EQ(update_expiry_count, 3);
  EXPECT_EQ(notify_count, 3);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
#ifndef NINSPECT
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
#endif  // NINSPECT

  conn_token.reset();
  EXPECT_EQ(update_expiry_count, 4);
  EXPECT_EQ(notify_count, 4);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(),
            Peer::ConnectionState::kInitializing);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectLowEnergyConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
#endif  // NINSPECT

  init_token.reset();
  EXPECT_EQ(update_expiry_count, 5);
  EXPECT_EQ(notify_count, 5);
  EXPECT_TRUE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(),
            Peer::ConnectionState::kNotConnected);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectLowEnergyConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
#endif  // NINSPECT
}

TEST_F(PeerTest,
       RegisterAndUnregisterInitializingLowEnergyConnectionDuringConnection) {
  SetUpPeer(/*address=*/kAddrLeRandom, /*connectable=*/true);

  int update_expiry_count = 0;
  set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
  int notify_count = 0;
  set_notify_listeners_cb(
      [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });

  std::optional<Peer::ConnectionToken> conn_token =
      peer().MutLe().RegisterConnection();
  // A notification and expiry update are sent when the peer becomes
  // non-temporary, and a second notification and update expiry are sent because
  // the initializing connection is registered.
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 2);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
#ifndef NINSPECT
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
#endif  // NINSPECT

  std::optional<Peer::InitializingConnectionToken> init_token =
      peer().MutLe().RegisterInitializingConnection();
  // Initializing connections should not affect the expiry or notify listeners
  // for peers that are already connected.
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 2);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
#ifndef NINSPECT
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
#endif  // NINSPECT

  init_token.reset();
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 2);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
#ifndef NINSPECT
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
#endif  // NINSPECT

  conn_token.reset();
  EXPECT_EQ(update_expiry_count, 3);
  EXPECT_EQ(notify_count, 3);
  EXPECT_TRUE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(),
            Peer::ConnectionState::kNotConnected);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectLowEnergyConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
#endif  // NINSPECT
}

TEST_F(PeerTest, RegisterAndUnregisterTwoLowEnergyInitializingConnections) {
  SetUpPeer(/*address=*/kAddrLeRandom, /*connectable=*/true);

  int update_expiry_count = 0;
  set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
  int notify_count = 0;
  set_notify_listeners_cb(
      [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });

  std::optional<Peer::InitializingConnectionToken> token_0 =
      peer().MutLe().RegisterInitializingConnection();
  // A notification and expiry update are sent when the peer becomes
  // non-temporary, and a second notification and update expiry are sent because
  // the initializing connection is registered.
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 2);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(),
            Peer::ConnectionState::kInitializing);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectLowEnergyConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
#endif  // NINSPECT

  std::optional<Peer::InitializingConnectionToken> token_1 =
      peer().MutLe().RegisterInitializingConnection();
  // The second initializing connection should not update expiry or notify.
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 2);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(),
            Peer::ConnectionState::kInitializing);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectLowEnergyConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
#endif  // NINSPECT

  token_0.reset();
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 2);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(),
            Peer::ConnectionState::kInitializing);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectLowEnergyConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
#endif  // NINSPECT
  token_1.reset();
  EXPECT_EQ(update_expiry_count, 3);
  EXPECT_EQ(notify_count, 3);
  // The peer's identity is not known, so it should become temporary upon
  // disconnection.
  EXPECT_TRUE(peer().temporary());
  EXPECT_EQ(peer().le()->connection_state(),
            Peer::ConnectionState::kNotConnected);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectLowEnergyConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
#endif  // NINSPECT
}

TEST_F(PeerTest, MovingLowEnergyConnectionTokenWorksAsExpected) {
  std::optional<Peer::ConnectionToken> token_0 =
      peer().MutLe().RegisterConnection();
  EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);

  std::optional<Peer::ConnectionToken> token_1 = std::move(token_0);
  EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);

  token_0.reset();
  EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);

  token_1.reset();
  EXPECT_EQ(peer().le()->connection_state(),
            Peer::ConnectionState::kNotConnected);
}

TEST_F(PeerTest, RegisterNamesWithVariousSources) {
  ASSERT_FALSE(peer().name().has_value());
  ASSERT_TRUE(peer().RegisterName("test", Peer::kAdvertisingDataComplete));

  // Test that name with lower source priority does not replace stored name with
  // higher priority.
  ASSERT_FALSE(peer().RegisterName("test", Peer::kUnknown));

  // Test that name with higher source priority replaces stored name with lower
  // priority.
  ASSERT_TRUE(peer().RegisterName("test", Peer::kGenericAccessService));

  // Test that stored name is not replaced with an identical name from an
  // identical source.
  ASSERT_FALSE(peer().RegisterName("test", Peer::kGenericAccessService));

  // Test that stored name is replaced by a different name from the same source.
  ASSERT_TRUE(
      peer().RegisterName("different_name", Peer::kGenericAccessService));
}

TEST_F(PeerTest, SetValidAdvertisingData) {
  constexpr const char* kLocalName = "Test";
  StaticByteBuffer raw_data{
      // Length - Type - Value formatted Local name
      0x05,
      static_cast<uint8_t>(DataType::kCompleteLocalName),
      kLocalName[0],
      kLocalName[1],
      kLocalName[2],
      kLocalName[3],
  };
  peer().MutLe().SetAdvertisingData(
      /*rssi=*/32, raw_data, pw::chrono::SystemClock::time_point());
  // Setting an AdvertisingData with a local name field should update the peer's
  // local name.
  ASSERT_TRUE(peer().name().has_value());
  EXPECT_EQ(kLocalName, peer().name().value());
  EXPECT_EQ(Peer::NameSource::kAdvertisingDataComplete, peer().name_source());
#ifndef NINSPECT
  EXPECT_EQ(0, InspectAdvertisingDataParseFailureCount());
  EXPECT_EQ("", InspectLastAdvertisingDataParseFailure());
#endif  // NINSPECT
}

TEST_F(PeerTest, SetShortenedLocalName) {
  constexpr const char* kLocalName = "Test";
  StaticByteBuffer raw_data{
      // Length - Type - Value formatted Local name
      0x05,
      static_cast<uint8_t>(DataType::kShortenedLocalName),
      kLocalName[0],
      kLocalName[1],
      kLocalName[2],
      kLocalName[3],
  };
  peer().MutLe().SetAdvertisingData(
      /*rssi=*/32, raw_data, pw::chrono::SystemClock::time_point());
  ASSERT_TRUE(peer().name().has_value());
  EXPECT_EQ(kLocalName, peer().name().value());
  EXPECT_EQ(Peer::NameSource::kAdvertisingDataShortened, peer().name_source());
}

TEST_F(PeerTest, SetInvalidAdvertisingData) {
  peer().MutLe().SetAdvertisingData(
      /*rssi=*/32, kInvalidAdvData, pw::chrono::SystemClock::time_point());

#ifndef NINSPECT
  EXPECT_EQ(1, InspectAdvertisingDataParseFailureCount());
  EXPECT_EQ(AdvertisingData::ParseErrorToString(
                AdvertisingData::ParseError::kUuidsMalformed),
            InspectLastAdvertisingDataParseFailure());
#endif  // NINSPECT
}

TEST_F(PeerDeathTest, RegisterTwoBrEdrConnectionsAsserts) {
  SetUpPeer(/*address=*/kAddrBrEdr, /*connectable=*/true);
  std::optional<Peer::ConnectionToken> token_0 =
      peer().MutBrEdr().RegisterConnection();
  ASSERT_DEATH_IF_SUPPORTED(
      {
        std::optional<Peer::ConnectionToken> token_1 =
            peer().MutBrEdr().RegisterConnection();
      },
      ".*already registered.*");
}

TEST_F(PeerTest,
       RegisterAndUnregisterInitializingBrEdrConnectionLeavesPeerTemporary) {
  SetUpPeer(/*address=*/kAddrBrEdr, /*connectable=*/true);
  EXPECT_TRUE(peer().identity_known());
  std::optional<Peer::InitializingConnectionToken> token =
      peer().MutBrEdr().RegisterInitializingConnection();
  EXPECT_FALSE(peer().temporary());
  token.reset();
  EXPECT_TRUE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kNotConnected);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectBrEdrConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
#endif  // NINSPECT
}

TEST_F(PeerTest, RegisterAndUnregisterBrEdrConnectionWithoutBonding) {
  SetUpPeer(/*address=*/kAddrBrEdr, /*connectable=*/true);

  int update_expiry_count = 0;
  set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
  int notify_count = 0;
  set_notify_listeners_cb(
      [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });

  std::optional<Peer::ConnectionToken> conn_token =
      peer().MutBrEdr().RegisterConnection();
  // A notification and expiry update are sent when the peer becomes
  // non-temporary, and a second notification and update expiry are sent because
  // the initializing connection is registered.
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 2);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kConnected);
#ifndef NINSPECT
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
#endif  // NINSPECT

  conn_token.reset();
  EXPECT_EQ(update_expiry_count, 3);
  EXPECT_EQ(notify_count, 3);
  // BR/EDR peers should become non-temporary after disconnecting if not bonded.
  EXPECT_TRUE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kNotConnected);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectBrEdrConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
#endif  // NINSPECT
}

TEST_F(PeerTest, RegisterAndUnregisterBrEdrConnectionWithBonding) {
  SetUpPeer(/*address=*/kAddrBrEdr, /*connectable=*/true);

  int update_expiry_count = 0;
  set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
  int notify_count = 0;
  set_notify_listeners_cb(
      [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });

  std::optional<Peer::ConnectionToken> conn_token =
      peer().MutBrEdr().RegisterConnection();
  // A notification and expiry update are sent when the peer becomes
  // non-temporary, and a second notification and update expiry are sent because
  // the initializing connection is registered.
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 2);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kConnected);
#ifndef NINSPECT
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
#endif  // NINSPECT

  peer().MutBrEdr().SetBondData(kSecureBrEdrKey);
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 3);

  conn_token.reset();
  EXPECT_EQ(update_expiry_count, 3);
  EXPECT_EQ(notify_count, 4);
  // Bonded BR/EDR peers should remain non-temporary after disconnecting.
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kNotConnected);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectBrEdrConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
#endif  // NINSPECT
}

TEST_F(PeerTest,
       RegisterAndUnregisterBrEdrConnectionDuringInitializingConnection) {
  SetUpPeer(/*address=*/kAddrBrEdr, /*connectable=*/true);

  int update_expiry_count = 0;
  set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
  int notify_count = 0;
  set_notify_listeners_cb(
      [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });

  std::optional<Peer::InitializingConnectionToken> init_token =
      peer().MutBrEdr().RegisterInitializingConnection();
  // Expiry is updated for state change + becoming non-temporary.
  EXPECT_EQ(update_expiry_count, 2);
  // 1 notification for becoming non-temporary.
  EXPECT_EQ(notify_count, 1);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kInitializing);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectBrEdrConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
#endif  // NINSPECT

  // The connection state should not change when registering a connection
  // because the peer is still initializing.
  std::optional<Peer::ConnectionToken> conn_token =
      peer().MutBrEdr().RegisterConnection();
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 1);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kInitializing);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectBrEdrConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
#endif  // NINSPECT

  conn_token.reset();
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 1);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kInitializing);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectBrEdrConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
#endif  // NINSPECT

  init_token.reset();
  EXPECT_EQ(update_expiry_count, 3);
  EXPECT_EQ(notify_count, 1);
  EXPECT_TRUE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kNotConnected);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectBrEdrConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
#endif  // NINSPECT
}

TEST_F(
    PeerTest,
    RegisterBrEdrConnectionDuringInitializingConnectionAndThenCompleteInitialization) {
  SetUpPeer(/*address=*/kAddrBrEdr, /*connectable=*/true);

  int update_expiry_count = 0;
  set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
  int notify_count = 0;
  set_notify_listeners_cb(
      [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });

  std::optional<Peer::InitializingConnectionToken> init_token =
      peer().MutBrEdr().RegisterInitializingConnection();
  // Expiry is updated for state change + becoming non-temporary.
  EXPECT_EQ(update_expiry_count, 2);
  // 1 notification for becoming non-temporary.
  EXPECT_EQ(notify_count, 1);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kInitializing);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectBrEdrConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
#endif  // NINSPECT

  // The connection state should not change when registering a connection
  // because the peer is still initializing.
  std::optional<Peer::ConnectionToken> conn_token =
      peer().MutBrEdr().RegisterConnection();
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 1);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kInitializing);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectBrEdrConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
#endif  // NINSPECT

  // When initialization completes, the connection state should become
  // kConnected.
  init_token.reset();
  EXPECT_EQ(update_expiry_count, 3);
  EXPECT_EQ(notify_count, 2);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kConnected);
#ifndef NINSPECT
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
#endif  // NINSPECT

  conn_token.reset();
  EXPECT_EQ(update_expiry_count, 4);
  EXPECT_EQ(notify_count, 3);
  EXPECT_TRUE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kNotConnected);
#ifndef NINSPECT
  EXPECT_EQ(
      InspectBrEdrConnectionState(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
#endif  // NINSPECT
}

TEST_F(PeerDeathTest,
       RegisterInitializingBrEdrConnectionDuringConnectionAsserts) {
  SetUpPeer(/*address=*/kAddrBrEdr, /*connectable=*/true);

  int update_expiry_count = 0;
  set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
  int notify_count = 0;
  set_notify_listeners_cb(
      [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });

  std::optional<Peer::ConnectionToken> conn_token =
      peer().MutBrEdr().RegisterConnection();
  // A notification and expiry update are sent when the peer becomes
  // non-temporary, and a second notification and update expiry are sent because
  // the initializing connection is registered.
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 2);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kConnected);
#ifndef NINSPECT
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
#endif  // NINSPECT

  // Registering an initializing connection when the peer is already connected
  // should assert.
  ASSERT_DEATH_IF_SUPPORTED(
      {
        Peer::InitializingConnectionToken init_token =
            peer().MutBrEdr().RegisterInitializingConnection();
      },
      ".*connected.*");
}

TEST_F(PeerTest, RegisterAndUnregisterTwoBrEdrInitializingConnections) {
  SetUpPeer(/*address=*/kAddrBrEdr, /*connectable=*/true);

  int update_expiry_count = 0;
  set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
  int notify_count = 0;
  set_notify_listeners_cb(
      [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });

  std::optional<Peer::InitializingConnectionToken> token_0 =
      peer().MutBrEdr().RegisterInitializingConnection();
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 1);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kInitializing);
#ifndef NINSPECT
  std::optional<std::string> inspect_conn_state = InspectBrEdrConnectionState();
  ASSERT_TRUE(inspect_conn_state);
  EXPECT_EQ(
      inspect_conn_state.value(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
#endif  // NINSPECT

  std::optional<Peer::InitializingConnectionToken> token_1 =
      peer().MutBrEdr().RegisterInitializingConnection();
  // The second initializing connection should not update expiry or notify.
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 1);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kInitializing);
#ifndef NINSPECT
  inspect_conn_state = InspectBrEdrConnectionState();
  ASSERT_TRUE(inspect_conn_state);
  EXPECT_EQ(
      inspect_conn_state.value(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
#endif  // NINSPECT

  token_0.reset();
  EXPECT_EQ(update_expiry_count, 2);
  EXPECT_EQ(notify_count, 1);
  EXPECT_FALSE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kInitializing);
#ifndef NINSPECT
  inspect_conn_state = InspectBrEdrConnectionState();
  ASSERT_TRUE(inspect_conn_state);
  EXPECT_EQ(
      inspect_conn_state.value(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
#endif  // NINSPECT

  token_1.reset();
  EXPECT_EQ(update_expiry_count, 3);
  EXPECT_EQ(notify_count, 1);
  EXPECT_TRUE(peer().temporary());
  EXPECT_EQ(peer().bredr()->connection_state(),
            Peer::ConnectionState::kNotConnected);
#ifndef NINSPECT
  inspect_conn_state = InspectBrEdrConnectionState();
  ASSERT_TRUE(inspect_conn_state);
  EXPECT_EQ(
      inspect_conn_state.value(),
      Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
#endif  // NINSPECT
}

TEST_F(PeerTest, SettingLeAdvertisingDataOfBondedPeerDoesNotUpdateName) {
  peer().RegisterName("alice");
  sm::PairingData data;
  data.peer_ltk = kLTK;
  data.local_ltk = kLTK;
  peer().MutLe().SetBondData(data);

  const StaticByteBuffer kAdvData(0x08,  // Length
                                  0x09,  // AD type: Complete Local Name
                                  'M',
                                  'a',
                                  'l',
                                  'l',
                                  'o',
                                  'r',
                                  'y');
  peer().MutLe().SetAdvertisingData(
      /*rssi=*/0,
      kAdvData,
      pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));

  ASSERT_TRUE(peer().name().has_value());
  EXPECT_EQ(peer().name().value(), "alice");
}

TEST_F(PeerTest, SettingInquiryDataOfBondedPeerDoesNotUpdateName) {
  peer().RegisterName("alice");
  peer().MutBrEdr().SetBondData(kLTK);

  const StaticByteBuffer kEirData(0x08,  // Length
                                  0x09,  // AD type: Complete Local Name
                                  'M',
                                  'a',
                                  'l',
                                  'l',
                                  'o',
                                  'r',
                                  'y');
  StaticPacket<pw::bluetooth::emboss::ExtendedInquiryResultEventWriter> eirep;
  eirep.view().num_responses().Write(1);
  eirep.view().bd_addr().CopyFrom(peer().address().value().view());
  eirep.view().extended_inquiry_response().BackingStorage().CopyFrom(
      ::emboss::support::ReadOnlyContiguousBuffer(&kEirData), kEirData.size());

  peer().MutBrEdr().SetInquiryData(eirep.view());

  ASSERT_TRUE(peer().name().has_value());
  EXPECT_EQ(peer().name().value(), "alice");
}

TEST_F(PeerTest, BrEdrDataSetEirDataDoesUpdatePeerName) {
  peer().MutBrEdr();  // Initialize BrEdrData.
  ASSERT_FALSE(peer().name().has_value());

  bool listener_notified = false;
  set_notify_listeners_cb(
      [&](auto&, Peer::NotifyListenersChange) { listener_notified = true; });

  const StaticByteBuffer kEirData(0x0D,  // Length (13)
                                  0x09,  // AD type: Complete Local Name
                                  'S',
                                  'a',
                                  'p',
                                  'p',
                                  'h',
                                  'i',
                                  'r',
                                  'e',
                                  0xf0,
                                  0x9f,
                                  0x92,
                                  0x96);

  StaticPacket<pw::bluetooth::emboss::ExtendedInquiryResultEventWriter> eirep;
  eirep.view().num_responses().Write(1);
  eirep.view().bd_addr().CopyFrom(peer().address().value().view());
  eirep.view().extended_inquiry_response().BackingStorage().CopyFrom(
      ::emboss::support::ReadOnlyContiguousBuffer(&kEirData), kEirData.size());

  peer().MutBrEdr().SetInquiryData(eirep.view());

  EXPECT_TRUE(listener_notified);  // Fresh EIR data results in an update
  ASSERT_TRUE(peer().name().has_value());
  EXPECT_EQ(peer().name().value(), "Sapphire💖");
}

TEST_F(PeerTest, SetEirDataUpdatesServiceUUIDs) {
  peer().MutBrEdr();  // Initialize BrEdrData.
                      // clang-format off
  const StaticByteBuffer kEirJustServiceUuids{
      // One 16-bit UUID: AudioSink
      0x03, static_cast<uint8_t>(DataType::kIncomplete16BitServiceUuids), 0x0A, 0x11,
  };

  StaticPacket<pw::bluetooth::emboss::ExtendedInquiryResultEventWriter> eirep;
  eirep.view().num_responses().Write(1);
  eirep.view().bd_addr().CopyFrom(peer().address().value().view());
  eirep.view().extended_inquiry_response().BackingStorage().CopyFrom(
      ::emboss::support::ReadOnlyContiguousBuffer(&kEirJustServiceUuids),
      kEirJustServiceUuids.size());
  peer().MutBrEdr().SetInquiryData(eirep.view());

  EXPECT_EQ(peer().bredr()->services().size(), 1u);
  EXPECT_EQ(peer().bredr()->services().count(UUID((uint16_t)0x110A)), 1u);
}

TEST_F(PeerTest, LowEnergyStoreBondCallsCallback) {
  int cb_count = 0;
  set_store_le_bond_cb([&cb_count](const sm::PairingData& data) {
    cb_count++;
    return true;
  });

  sm::PairingData data;
  data.peer_ltk = kLTK;
  data.local_ltk = kLTK;
  EXPECT_TRUE(peer().MutLe().StoreBond(data));
  EXPECT_EQ(cb_count, 1);
}

}  // namespace
}  // namespace bt::gap
