// 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/gap/peer.h"

#include <lib/inspect/testing/cpp/inspect.h>

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

#include "lib/gtest/test_loop_fixture.h"
#include "src/connectivity/bluetooth/core/bt-host/common/advertising_data.h"
#include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/common/manufacturer_names.h"
#include "src/connectivity/bluetooth/core/bt-host/hci-spec/util.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/inspect_util.h"

namespace bt::gap {
namespace {

using namespace inspect::testing;
using bt::testing::GetInspectValue;
using bt::testing::ReadInspect;

constexpr uint16_t kManufacturer = 0x0001;
constexpr uint16_t kSubversion = 0x0002;

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 ::gtest::TestLoopFixture {
 public:
  PeerTest() = default;

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

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

 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_);
    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_; }

  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});
    ZX_ASSERT(val);
    return *val;
  }

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

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

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

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

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

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

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

  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 {};

TEST_F(PeerTest, InspectHierarchy) {
  peer().set_version(hci_spec::HCIVersion::k5_0, kManufacturer, kSubversion);

  peer().SetName("Sapphire💖");

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

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

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

  // 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())),
        BoolIs(Peer::BrEdrData::kInspectLinkKeyName, peer().bredr()->bonded()),
        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()),
        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))));
}

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, zx::time());
  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
  );
  hci_spec::ExtendedInquiryResultEventParams eirep;
  eirep.num_responses = 1;
  eirep.bd_addr = peer().address().value();
  MutableBufferView(eirep.extended_inquiry_response, sizeof(eirep.extended_inquiry_response))
      .Write(kEirData);

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

TEST_F(PeerTest, SetNameWithInvalidUtf8NameDoesNotUpdatePeerName) {
  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().SetName(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, zx::time(1));
  ASSERT_TRUE(peer().MutLe().parsed_advertising_data_timestamp());
  EXPECT_EQ(peer().MutLe().parsed_advertising_data_timestamp().value(), zx::time(1));

  peer().MutLe().SetAdvertisingData(/*rssi=*/0, kAdvData, zx::time(2));
  ASSERT_TRUE(peer().MutLe().parsed_advertising_data_timestamp());
  EXPECT_EQ(peer().MutLe().parsed_advertising_data_timestamp().value(), zx::time(2));

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

TEST_F(PeerTest, SettingLowEnergyAdvertisingDataUpdatesLastUpdated) {
  EXPECT_EQ(peer().last_updated(), zx::time(0));

  int notify_count = 0;
  set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
    EXPECT_EQ(peer().last_updated(), zx::time(2));
    notify_count++;
  });

  RunLoopFor(zx::duration(2));
  peer().MutLe().SetAdvertisingData(/*rssi=*/0, kAdvData, zx::time(1));
  EXPECT_EQ(peer().last_updated(), zx::time(2));
  EXPECT_GE(notify_count, 1);
}

TEST_F(PeerTest, RegisteringLowEnergyInitializingConnectionUpdatesLastUpdated) {
  EXPECT_EQ(peer().last_updated(), zx::time(0));

  int notify_count = 0;
  set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
    EXPECT_EQ(peer().last_updated(), zx::time(2));
    notify_count++;
  });

  RunLoopFor(zx::duration(2));
  Peer::InitializingConnectionToken token = peer().MutLe().RegisterInitializingConnection();
  EXPECT_EQ(peer().last_updated(), zx::time(2));
  EXPECT_GE(notify_count, 1);
}

TEST_F(PeerTest, SettingLowEnergyBondDataUpdatesLastUpdated) {
  EXPECT_EQ(peer().last_updated(), zx::time(0));

  int notify_count = 0;
  set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
    EXPECT_EQ(peer().last_updated(), zx::time(2));
    notify_count++;
  });

  RunLoopFor(zx::duration(2));
  sm::PairingData data;
  data.peer_ltk = kLTK;
  data.local_ltk = kLTK;
  peer().MutLe().SetBondData(data);
  EXPECT_EQ(peer().last_updated(), zx::time(2));
  EXPECT_GE(notify_count, 1);
}

TEST_F(PeerTest, RegisteringBrEdrInitializingConnectionUpdatesLastUpdated) {
  EXPECT_EQ(peer().last_updated(), zx::time(0));

  int notify_count = 0;
  set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
    EXPECT_EQ(peer().last_updated(), zx::time(2));
    notify_count++;
  });

  RunLoopFor(zx::duration(2));
  Peer::InitializingConnectionToken token = peer().MutBrEdr().RegisterInitializingConnection();
  EXPECT_EQ(peer().last_updated(), zx::time(2));
  EXPECT_GE(notify_count, 1);
}

TEST_F(PeerTest, SettingInquiryDataUpdatesLastUpdated) {
  SetUpPeer(/*address=*/kAddrLeAlias, /*connectable=*/true);
  EXPECT_EQ(peer().last_updated(), zx::time(0));

  int notify_count = 0;
  set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
    EXPECT_EQ(peer().last_updated(), zx::time(2));
    notify_count++;
  });

  RunLoopFor(zx::duration(2));
  hci_spec::InquiryResult ir;
  ir.bd_addr = kAddrLeAlias.value();
  peer().MutBrEdr().SetInquiryData(ir);
  EXPECT_EQ(peer().last_updated(), zx::time(2));
  EXPECT_GE(notify_count, 1);
}

TEST_F(PeerTest, SettingBrEdrBondDataUpdatesLastUpdated) {
  EXPECT_EQ(peer().last_updated(), zx::time(0));

  int notify_count = 0;
  set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
    EXPECT_EQ(peer().last_updated(), zx::time(2));
    notify_count++;
  });

  RunLoopFor(zx::duration(2));
  peer().MutBrEdr().SetBondData(kSecureBrEdrKey);
  EXPECT_EQ(peer().last_updated(), zx::time(2));
  EXPECT_GE(notify_count, 1);
}

TEST_F(PeerTest, SettingAddingBrEdrServiceUpdatesLastUpdated) {
  EXPECT_EQ(peer().last_updated(), zx::time(0));

  int notify_count = 0;
  set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
    EXPECT_EQ(peer().last_updated(), zx::time(2));
    notify_count++;
  });

  RunLoopFor(zx::duration(2));
  peer().MutBrEdr().AddService(UUID(uint16_t{0x110b}));
  EXPECT_EQ(peer().last_updated(), zx::time(2));
  EXPECT_GE(notify_count, 1);
}

TEST_F(PeerTest, SettingNameUpdatesLastUpdated) {
  EXPECT_EQ(peer().last_updated(), zx::time(0));

  int notify_count = 0;
  set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
    EXPECT_EQ(peer().last_updated(), zx::time(2));
    notify_count++;
  });

  RunLoopFor(zx::duration(2));
  peer().SetName("name");
  EXPECT_EQ(peer().last_updated(), zx::time(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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
  EXPECT_EQ(MetricsLowEnergyConnections(), 1u);

  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);
  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);

  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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
  EXPECT_EQ(MetricsLowEnergyDisconnections(), 1u);

  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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
  EXPECT_EQ(MetricsLowEnergyDisconnections(), 2u);
}

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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
}

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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
}

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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));

  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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));

  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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));

  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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
}

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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));

  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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));

  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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));

  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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
}

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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));

  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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));

  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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
  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);
  EXPECT_EQ(InspectLowEnergyConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
}

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, 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, zx::time());
  // 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(0, InspectAdvertisingDataParseFailureCount());
  EXPECT_EQ("", InspectLastAdvertisingDataParseFailure());
}

TEST_F(PeerTest, SetInvalidAdvertisingData) {
  peer().MutLe().SetAdvertisingData(/*rssi=*/32, kInvalidAdvData, zx::time());

  EXPECT_EQ(1, InspectAdvertisingDataParseFailureCount());
  EXPECT_EQ(AdvertisingData::ParseErrorToString(AdvertisingData::ParseError::kUuidsMalformed),
            InspectLastAdvertisingDataParseFailure());
}

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);
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
}

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);
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));

  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);
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
}

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);
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));

  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);
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
}

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);
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));

  // 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);
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));

  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);
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));

  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);
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
}

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);
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));

  // 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);
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));

  // 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);
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));

  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);
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
}

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);
  EXPECT_EQ(InspectBrEdrConnectionState(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));

  // 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);
  std::optional<std::string> inspect_conn_state = InspectBrEdrConnectionState();
  ASSERT_TRUE(inspect_conn_state);
  EXPECT_EQ(inspect_conn_state.value(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));

  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);
  inspect_conn_state = InspectBrEdrConnectionState();
  ASSERT_TRUE(inspect_conn_state);
  EXPECT_EQ(inspect_conn_state.value(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));

  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);
  inspect_conn_state = InspectBrEdrConnectionState();
  ASSERT_TRUE(inspect_conn_state);
  EXPECT_EQ(inspect_conn_state.value(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));

  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);
  inspect_conn_state = InspectBrEdrConnectionState();
  ASSERT_TRUE(inspect_conn_state);
  EXPECT_EQ(inspect_conn_state.value(),
            Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
}

TEST_F(PeerTest, SettingLeAdvertisingDataOfBondedPeerDoesNotUpdateName) {
  peer().SetName("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, zx::time(0));

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

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

  const StaticByteBuffer kEirData(0x08,  // Length
                                  0x09,  // AD type: Complete Local Name
                                  'M', 'a', 'l', 'l', 'o', 'r', 'y');
  hci_spec::ExtendedInquiryResultEventParams eirep;
  eirep.num_responses = 1;
  eirep.bd_addr = peer().address().value();
  MutableBufferView(eirep.extended_inquiry_response, sizeof(eirep.extended_inquiry_response))
      .Write(kEirData);
  peer().MutBrEdr().SetInquiryData(eirep);

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

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
