// Copyright 2017 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/low_energy_connection_manager.h"

#include <lib/fit/function.h>
#include <lib/inspect/testing/cpp/inspect.h>
#include <zircon/assert.h>

#include <cstddef>
#include <limits>
#include <memory>
#include <vector>

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

#include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/common/device_address.h"
#include "src/connectivity/bluetooth/core/bt-host/common/random.h"
#include "src/connectivity/bluetooth/core/bt-host/gap/fake_pairing_delegate.h"
#include "src/connectivity/bluetooth/core/bt-host/gap/gap.h"
#include "src/connectivity/bluetooth/core/bt-host/gap/low_energy_address_manager.h"
#include "src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager.h"
#include "src/connectivity/bluetooth/core/bt-host/gap/peer.h"
#include "src/connectivity/bluetooth/core/bt-host/gap/peer_cache.h"
#include "src/connectivity/bluetooth/core/bt-host/gatt/fake_layer.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/defaults.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/fake_local_address_delegate.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/hci_constants.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/legacy_low_energy_scanner.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/low_energy_connector.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/util.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/fake_channel.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/fake_channel_test.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/fake_l2cap.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/l2cap_defs.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/smp.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/test_security_manager.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/types.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/controller_test.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/fake_controller.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/fake_peer.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/test_packets.h"

namespace bt::gap {
namespace {

using namespace inspect::testing;

using bt::sm::BondableMode;
using bt::testing::FakeController;
using bt::testing::FakePeer;

using TestingBase = bt::testing::ControllerTest<FakeController>;
using l2cap::testing::FakeChannel;
using TestSm = sm::testing::TestSecurityManager;
using TestSmFactory = sm::testing::TestSecurityManagerFactory;
using ConnectionResult = LowEnergyConnectionManager::ConnectionResult;

const DeviceAddress kAddress0(DeviceAddress::Type::kLEPublic, {1});
const DeviceAddress kAddrAlias0(DeviceAddress::Type::kBREDR, kAddress0.value());
const DeviceAddress kAddress1(DeviceAddress::Type::kLERandom, {2});
const DeviceAddress kAddress2(DeviceAddress::Type::kBREDR, {3});
const DeviceAddress kAddress3(DeviceAddress::Type::kLEPublic, {4});
const DeviceAddress kAdapterAddress(DeviceAddress::Type::kLEPublic, {9});

const size_t kLEMaxNumPackets = 10;
const hci::DataBufferInfo kLEDataBufferInfo(hci::kMaxACLPayloadSize, kLEMaxNumPackets);

constexpr std::array kConnectDelays = {zx::sec(0), zx::sec(2), zx::sec(4)};

const LowEnergyConnectionOptions kConnectionOptions{};

class LowEnergyConnectionManagerTest : public TestingBase {
 public:
  LowEnergyConnectionManagerTest() = default;
  ~LowEnergyConnectionManagerTest() override = default;

 protected:
  void SetUp() override {
    TestingBase::SetUp();

    // Initialize with LE buffers only.
    TestingBase::InitializeACLDataChannel(hci::DataBufferInfo(), kLEDataBufferInfo);

    FakeController::Settings settings;
    settings.ApplyLegacyLEConfig();
    test_device()->set_settings(settings);

    peer_cache_ = std::make_unique<PeerCache>();
    l2cap_ = l2cap::testing::FakeL2cap::Create();

    connector_ = std::make_unique<hci::LowEnergyConnector>(
        transport()->WeakPtr(), &addr_delegate_, dispatcher(),
        fit::bind_member(this, &LowEnergyConnectionManagerTest::OnIncomingConnection));

    gatt_ = std::make_unique<gatt::testing::FakeLayer>();
    sm_factory_ = std::make_unique<TestSmFactory>();

    address_manager_ = std::make_unique<LowEnergyAddressManager>(
        kAdapterAddress, /*delegate=*/[] { return false; }, transport()->WeakPtr());
    scanner_ = std::make_unique<hci::LegacyLowEnergyScanner>(address_manager_.get(),
                                                             transport()->WeakPtr(), dispatcher());
    discovery_manager_ = std::make_unique<LowEnergyDiscoveryManager>(
        transport()->WeakPtr(), scanner_.get(), peer_cache_.get());
    conn_mgr_ = std::make_unique<LowEnergyConnectionManager>(
        transport()->WeakPtr(), &addr_delegate_, connector_.get(), peer_cache_.get(), l2cap_,
        gatt_->AsWeakPtr(), discovery_manager_->GetWeakPtr(),
        fit::bind_member(sm_factory_.get(), &TestSmFactory::CreateSm));

    test_device()->set_connection_state_callback(
        fit::bind_member(this, &LowEnergyConnectionManagerTest::OnConnectionStateChanged));
    StartTestDevice();
  }

  void TearDown() override {
    if (conn_mgr_) {
      conn_mgr_ = nullptr;
    }
    discovery_manager_ = nullptr;
    scanner_ = nullptr;
    address_manager_ = nullptr;
    gatt_ = nullptr;
    connector_ = nullptr;
    peer_cache_ = nullptr;

    l2cap_ = nullptr;

    TestingBase::TearDown();
  }

  // Deletes |conn_mgr_|.
  void DeleteConnMgr() { conn_mgr_ = nullptr; }

  PeerCache* peer_cache() const { return peer_cache_.get(); }
  LowEnergyConnectionManager* conn_mgr() const { return conn_mgr_.get(); }
  l2cap::testing::FakeL2cap* fake_l2cap() const { return l2cap_.get(); }
  gatt::testing::FakeLayer* fake_gatt() { return gatt_.get(); }
  LowEnergyDiscoveryManager* discovery_mgr() { return discovery_manager_.get(); }

  // Addresses of currently connected fake peers.
  using PeerList = std::unordered_set<DeviceAddress>;
  const PeerList& connected_peers() const { return connected_peers_; }

  // Addresses of peers with a canceled connection attempt.
  const PeerList& canceled_peers() const { return canceled_peers_; }

  hci::ConnectionPtr MoveLastRemoteInitiated() { return std::move(last_remote_initiated_); }

  fxl::WeakPtr<TestSm> TestSmByHandle(hci::ConnectionHandle handle) {
    return sm_factory_->GetTestSm(handle);
  }

 private:
  // Called by |connector_| when a new remote initiated connection is received.
  void OnIncomingConnection(hci::ConnectionHandle handle, hci::Connection::Role role,
                            const DeviceAddress& peer_address,
                            const hci::LEConnectionParameters& conn_params) {
    DeviceAddress local_address(DeviceAddress::Type::kLEPublic, {3, 2, 1, 1, 2, 3});

    // Create a production connection object that can interact with the fake
    // controller.
    last_remote_initiated_ = hci::Connection::CreateLE(handle, role, local_address, peer_address,
                                                       conn_params, transport()->WeakPtr());
  }

  // Called by FakeController on connection events.
  void OnConnectionStateChanged(const DeviceAddress& address, hci::ConnectionHandle handle,
                                bool connected, bool canceled) {
    bt_log(DEBUG, "gap-test",
           "OnConnectionStateChanged: %s (handle: %#.4x) (connected: %s) (canceled: %s):\n",
           address.ToString().c_str(), handle, (connected ? "true" : "false"),
           (canceled ? "true" : "false"));
    if (canceled) {
      canceled_peers_.insert(address);
    } else if (connected) {
      ZX_DEBUG_ASSERT(connected_peers_.find(address) == connected_peers_.end());
      connected_peers_.insert(address);
    } else {
      ZX_DEBUG_ASSERT(connected_peers_.find(address) != connected_peers_.end());
      connected_peers_.erase(address);
    }
  }

  fbl::RefPtr<l2cap::testing::FakeL2cap> l2cap_;

  hci::FakeLocalAddressDelegate addr_delegate_;
  std::unique_ptr<PeerCache> peer_cache_;
  std::unique_ptr<hci::LowEnergyConnector> connector_;
  std::unique_ptr<gatt::testing::FakeLayer> gatt_;
  std::unique_ptr<TestSmFactory> sm_factory_;
  std::unique_ptr<hci::LegacyLowEnergyScanner> scanner_;
  std::unique_ptr<LowEnergyAddressManager> address_manager_;
  std::unique_ptr<LowEnergyDiscoveryManager> discovery_manager_;
  std::unique_ptr<LowEnergyConnectionManager> conn_mgr_;

  // The most recent remote-initiated connection reported by |connector_|.
  hci::ConnectionPtr last_remote_initiated_;

  PeerList connected_peers_;
  PeerList canceled_peers_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(LowEnergyConnectionManagerTest);
};

using GAP_LowEnergyConnectionManagerTest = LowEnergyConnectionManagerTest;

TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectUnknownPeer) {
  constexpr PeerId kUnknownId(1);
  ConnectionResult result;
  conn_mgr()->Connect(
      kUnknownId, [&result](auto res) { result = std::move(res); }, kConnectionOptions);
  ASSERT_TRUE(result.is_error());
  EXPECT_EQ(result.error(), HostError::kNotFound);
}

TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectClassicPeer) {
  auto* peer = peer_cache()->NewPeer(kAddress2, true);
  ConnectionResult result;
  conn_mgr()->Connect(
      peer->identifier(), [&result](auto res) { result = std::move(res); }, kConnectionOptions);
  ASSERT_TRUE(result.is_error());
  EXPECT_EQ(result.error(), HostError::kNotFound);
}

TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectNonConnectablePeer) {
  auto* peer = peer_cache()->NewPeer(kAddress0, false);
  ConnectionResult result;
  conn_mgr()->Connect(
      peer->identifier(), [&result](auto res) { result = std::move(res); }, kConnectionOptions);
  ASSERT_TRUE(result.is_error());
  EXPECT_EQ(result.error(), HostError::kNotFound);
}

// An error is received via the HCI Command cb_status event
TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectSinglePeerErrorStatus) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  fake_peer->set_connect_status(hci::StatusCode::kConnectionFailedToBeEstablished);
  test_device()->AddPeer(std::move(fake_peer));

  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());

  ConnectionResult result;
  auto callback = [&result](auto res) { result = std::move(res); };

  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

  RunLoopUntilIdle();

  ASSERT_TRUE(result.is_error());
  EXPECT_EQ(HostError::kFailed, result.error());
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
}

// LE Connection Complete event reports error
TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectSinglePeerFailure) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  fake_peer->set_connect_response(hci::StatusCode::kConnectionFailedToBeEstablished);
  test_device()->AddPeer(std::move(fake_peer));

  ConnectionResult result;
  auto callback = [&result](auto res) { result = std::move(res); };

  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

  RunLoopUntilIdle();

  ASSERT_TRUE(result.is_error());
  EXPECT_EQ(HostError::kFailed, result.error());
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectSinglePeerScanTimeout) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);

  // We add no fake peers to cause the scan to time out.

  ConnectionResult result;
  auto callback = [&result](auto res) { result = std::move(res); };

  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

  RunLoopFor(kLEGeneralCepScanTimeout);

  ASSERT_TRUE(result.is_error());
  EXPECT_EQ(HostError::kTimedOut, result.error());
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectSinglePeerAlreadyInScanCache) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  // Ensure peer is in scan cache by doing active discovery.
  LowEnergyDiscoverySessionPtr session;
  discovery_mgr()->StartDiscovery(/*active=*/true,
                                  [&session](auto cb_session) { session = std::move(cb_session); });
  RunLoopUntilIdle();

  ConnectionResult result;
  auto callback = [&result](auto res) { result = std::move(res); };

  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  RunLoopUntilIdle();
  ASSERT_TRUE(result.is_ok());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectSinglePeerRequestTimeout) {
  constexpr zx::duration kTestRequestTimeout = zx::sec(20);

  auto* peer = peer_cache()->NewPeer(kAddress0, true);

  // Add a fake peer so that scan succeeds but connect stalls.
  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  fake_peer->set_force_pending_connect(true);
  test_device()->AddPeer(std::move(fake_peer));

  ConnectionResult result;
  auto callback = [&result](auto res) { result = std::move(res); };

  conn_mgr()->set_request_timeout_for_testing(kTestRequestTimeout);
  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

  RunLoopFor(kTestRequestTimeout);
  RunLoopUntilIdle();

  ASSERT_TRUE(result.is_error());
  EXPECT_EQ(HostError::kTimedOut, result.error());
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
}

// Tests that an entry in the cache does not expire while a connection attempt
// is pending.
TEST_F(GAP_LowEnergyConnectionManagerTest, PeerDoesNotExpireDuringTimeout) {
  // Set a connection timeout that is longer than the PeerCache expiry
  // timeout.
  // TODO(fxbug.dev/1418): Consider configuring the cache timeout explicitly rather than
  // relying on the kCacheTimeout constant.
  constexpr zx::duration kTestRequestTimeout = kCacheTimeout + zx::sec(1);
  conn_mgr()->set_request_timeout_for_testing(kTestRequestTimeout);

  // Note: Use a random address so that the peer becomes temporary upon failure.
  auto* peer = peer_cache()->NewPeer(kAddress1, true);
  EXPECT_TRUE(peer->temporary());

  ConnectionResult result;
  auto callback = [&result](auto res) { result = std::move(res); };

  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
  EXPECT_FALSE(peer->temporary());

  RunLoopFor(kTestRequestTimeout);
  ASSERT_TRUE(result.is_error());
  EXPECT_EQ(HostError::kTimedOut, result.error());
  EXPECT_EQ(peer, peer_cache()->FindByAddress(kAddress1));
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
  EXPECT_TRUE(peer->temporary());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, PeerDoesNotExpireDuringDelayedConnect) {
  // Make the connection resolve after a delay that is longer than the cache
  // timeout.
  constexpr zx::duration kConnectionDelay = kCacheTimeout + zx::sec(1);
  FakeController::Settings settings;
  settings.ApplyLegacyLEConfig();
  settings.le_connection_delay = kConnectionDelay;
  test_device()->set_settings(settings);

  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  auto id = peer->identifier();
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  // Make sure the connection request doesn't time out while waiting for a
  // response.
  conn_mgr()->set_request_timeout_for_testing(kConnectionDelay + zx::sec(1));

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto callback = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
    ASSERT_TRUE(conn_handle);
    EXPECT_TRUE(conn_handle->active());
  };
  conn_mgr()->Connect(id, callback, kConnectionOptions);
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

  RunLoopFor(kConnectionDelay);
  ASSERT_TRUE(conn_handle);

  // The peer should not have expired during this time.
  peer = peer_cache()->FindByAddress(kAddress0);
  ASSERT_TRUE(peer);
  EXPECT_EQ(id, peer->identifier());
  EXPECT_TRUE(peer->connected());
  EXPECT_FALSE(peer->temporary());
}

// Successful connection to single peer
TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectSinglePeer) {
  auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  std::optional<hci::LECreateConnectionCommandParams> connect_params;
  test_device()->set_le_create_connection_command_callback(
      [&](auto params) { connect_params = params; });

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto callback = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
    EXPECT_TRUE(conn_handle->active());
  };

  EXPECT_TRUE(connected_peers().empty());
  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

  RunLoopUntilIdle();

  EXPECT_EQ(1u, connected_peers().size());
  EXPECT_EQ(1u, connected_peers().count(kAddress0));

  ASSERT_TRUE(conn_handle);
  EXPECT_TRUE(conn_handle->active());
  EXPECT_EQ(peer->identifier(), conn_handle->peer_identifier());
  EXPECT_FALSE(peer->temporary());
  EXPECT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());
  ASSERT_TRUE(connect_params);
  EXPECT_EQ(letoh16(connect_params->scan_interval), kLEScanFastInterval);
  EXPECT_EQ(letoh16(connect_params->scan_window), kLEScanFastWindow);
}

struct TestObject final : fbl::RefCounted<TestObject> {
  explicit TestObject(bool* d) : deleted(d) {
    ZX_DEBUG_ASSERT(deleted);
    *deleted = false;
  }

  ~TestObject() { *deleted = true; }

  bool* deleted;
};

TEST_F(GAP_LowEnergyConnectionManagerTest, DeleteRefInClosedCallback) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  bool deleted = false;
  auto obj = fbl::AdoptRef(new TestObject(&deleted));
  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  int closed_count = 0;
  auto closed_cb = [&, obj = std::move(obj)] {
    closed_count++;
    conn_handle = nullptr;

    // The object should remain alive for the duration of this callback.
    EXPECT_FALSE(deleted);
  };

  auto success_cb = [&conn_handle, &closed_cb](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
    conn_handle->set_closed_callback(std::move(closed_cb));
  };

  conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
  RunLoopUntilIdle();

  ASSERT_TRUE(conn_handle);
  ASSERT_TRUE(conn_handle->active());

  // This will trigger the closed callback.
  EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
  RunLoopUntilIdle();

  EXPECT_EQ(1, closed_count);
  EXPECT_TRUE(connected_peers().empty());
  EXPECT_FALSE(conn_handle);

  // The object should be deleted.
  EXPECT_TRUE(deleted);
}

TEST_F(GAP_LowEnergyConnectionManagerTest, ReleaseRef) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto callback = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
    EXPECT_TRUE(conn_handle->active());
  };

  EXPECT_TRUE(connected_peers().empty());
  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);

  RunLoopUntilIdle();

  EXPECT_EQ(1u, connected_peers().size());
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());

  ASSERT_TRUE(conn_handle);
  conn_handle = nullptr;

  RunLoopUntilIdle();

  EXPECT_TRUE(connected_peers().empty());
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, OnePeerTwoPendingRequestsBothFail) {
  constexpr int kRequestCount = 2;

  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  fake_peer->set_connect_response(hci::StatusCode::kConnectionFailedToBeEstablished);
  test_device()->AddPeer(std::move(fake_peer));

  ConnectionResult results[kRequestCount];

  int cb_count = 0;
  auto callback = [&results, &cb_count](auto result) { results[cb_count++] = std::move(result); };

  for (int i = 0; i < kRequestCount; ++i) {
    conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  }

  RunLoopUntilIdle();

  ASSERT_EQ(kRequestCount, cb_count);
  for (int i = 0; i < kRequestCount; ++i) {
    ASSERT_TRUE(results[i].is_error());
    EXPECT_EQ(HostError::kFailed, results[i].error()) << "request count: " << i + 1;
  }
}

TEST_F(GAP_LowEnergyConnectionManagerTest, OnePeerManyPendingRequests) {
  constexpr size_t kRequestCount = 50;

  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
  auto callback = [&conn_handles](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handles.emplace_back(result.take_value());
  };

  for (size_t i = 0; i < kRequestCount; ++i) {
    conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  }

  RunLoopUntilIdle();

  EXPECT_EQ(1u, connected_peers().size());
  EXPECT_EQ(1u, connected_peers().count(kAddress0));

  EXPECT_EQ(kRequestCount, conn_handles.size());
  for (size_t i = 0; i < kRequestCount; ++i) {
    ASSERT_TRUE(conn_handles[i]);
    EXPECT_TRUE(conn_handles[i]->active());
    EXPECT_EQ(peer->identifier(), conn_handles[i]->peer_identifier());
  }

  // Release one reference. The rest should be active.
  conn_handles[0] = nullptr;
  for (size_t i = 1; i < kRequestCount; ++i)
    EXPECT_TRUE(conn_handles[i]->active());

  // Release all but one reference.
  for (size_t i = 1; i < kRequestCount - 1; ++i)
    conn_handles[i] = nullptr;
  EXPECT_TRUE(conn_handles[kRequestCount - 1]->active());

  // Drop the last reference.
  conn_handles[kRequestCount - 1] = nullptr;

  RunLoopUntilIdle();

  EXPECT_TRUE(connected_peers().empty());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, AddRefAfterConnection) {
  constexpr size_t kRefCount = 50;

  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
  auto callback = [&conn_handles](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handles.emplace_back(result.take_value());
  };

  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);

  RunLoopUntilIdle();

  EXPECT_EQ(1u, connected_peers().size());
  EXPECT_EQ(1u, connected_peers().count(kAddress0));
  EXPECT_EQ(1u, conn_handles.size());

  // Add new references.
  for (size_t i = 1; i < kRefCount; ++i) {
    conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
    RunLoopUntilIdle();
  }

  EXPECT_EQ(1u, connected_peers().size());
  EXPECT_EQ(1u, connected_peers().count(kAddress0));
  EXPECT_EQ(kRefCount, conn_handles.size());

  // Disconnect.
  conn_handles.clear();

  RunLoopUntilIdle();

  EXPECT_TRUE(connected_peers().empty());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, PendingRequestsOnTwoPeers) {
  auto* peer0 = peer_cache()->NewPeer(kAddress0, true);
  auto* peer1 = peer_cache()->NewPeer(kAddress1, true);

  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1));

  std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
  auto callback = [&conn_handles](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handles.emplace_back(result.take_value());
  };

  conn_mgr()->Connect(peer0->identifier(), callback, kConnectionOptions);
  conn_mgr()->Connect(peer1->identifier(), callback, kConnectionOptions);

  RunLoopUntilIdle();

  EXPECT_EQ(2u, connected_peers().size());
  EXPECT_EQ(1u, connected_peers().count(kAddress0));
  EXPECT_EQ(1u, connected_peers().count(kAddress1));

  ASSERT_EQ(2u, conn_handles.size());
  ASSERT_TRUE(conn_handles[0]);
  ASSERT_TRUE(conn_handles[1]);
  EXPECT_EQ(peer0->identifier(), conn_handles[0]->peer_identifier());
  EXPECT_EQ(peer1->identifier(), conn_handles[1]->peer_identifier());

  // |peer1| should disconnect first.
  conn_handles[1] = nullptr;

  RunLoopUntilIdle();

  EXPECT_EQ(1u, connected_peers().size());
  EXPECT_EQ(1u, connected_peers().count(kAddress0));

  conn_handles.clear();

  RunLoopUntilIdle();
  EXPECT_TRUE(connected_peers().empty());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, PendingRequestsOnTwoPeersOneFails) {
  auto* peer0 = peer_cache()->NewPeer(kAddress0, true);
  auto* peer1 = peer_cache()->NewPeer(kAddress1, true);

  auto fake_peer0 = std::make_unique<FakePeer>(kAddress0);
  fake_peer0->set_connect_response(hci::StatusCode::kConnectionFailedToBeEstablished);
  test_device()->AddPeer(std::move(fake_peer0));
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1));

  std::vector<ConnectionResult> conn_results;
  auto callback = [&conn_results](auto result) { conn_results.emplace_back(std::move(result)); };

  conn_mgr()->Connect(peer0->identifier(), callback, kConnectionOptions);
  conn_mgr()->Connect(peer1->identifier(), callback, kConnectionOptions);

  RunLoopUntilIdle();

  EXPECT_EQ(1u, connected_peers().size());
  EXPECT_EQ(1u, connected_peers().count(kAddress1));

  ASSERT_EQ(2u, conn_results.size());
  EXPECT_TRUE(conn_results[0].is_error());
  ASSERT_TRUE(conn_results[1].is_ok());
  EXPECT_EQ(peer1->identifier(), conn_results[1].value()->peer_identifier());

  // Both connections should disconnect.
  conn_results.clear();

  RunLoopUntilIdle();
  EXPECT_TRUE(connected_peers().empty());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, Destructor) {
  auto* peer0 = peer_cache()->NewPeer(kAddress0, true);
  auto* peer1 = peer_cache()->NewPeer(kAddress1, true);

  // Connecting to this peer will succeed.
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  // Connecting to this peer will remain pending.
  auto pending_peer = std::make_unique<FakePeer>(kAddress1);
  pending_peer->set_force_pending_connect(true);
  test_device()->AddPeer(std::move(pending_peer));

  // Below we create one connection and one pending request to have at the time
  // of destruction.

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto success_cb = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
  };

  conn_mgr()->Connect(peer0->identifier(), success_cb, kConnectionOptions);
  RunLoopUntilIdle();

  ASSERT_TRUE(conn_handle);
  bool conn_closed = false;
  conn_handle->set_closed_callback([&conn_closed] { conn_closed = true; });

  bool error_cb_called = false;
  auto error_cb = [&error_cb_called](auto result) {
    ASSERT_TRUE(result.is_error());
    EXPECT_EQ(HostError::kCanceled, result.error());
    error_cb_called = true;
  };

  // This will send an HCI command to the fake controller. We delete the
  // connection manager before a connection event gets received which should
  // cancel the connection.
  conn_mgr()->Connect(peer1->identifier(), error_cb, kConnectionOptions);
  RunLoopUntilIdle();
  EXPECT_FALSE(error_cb_called);

  DeleteConnMgr();

  RunLoopUntilIdle();

  EXPECT_TRUE(error_cb_called);
  EXPECT_TRUE(conn_closed);
  EXPECT_EQ(1u, canceled_peers().size());
  EXPECT_EQ(1u, canceled_peers().count(kAddress1));
}

TEST_F(GAP_LowEnergyConnectionManagerTest, DisconnectPendingConnectionWhileAwaitingScanStart) {
  auto peer_0 = peer_cache()->NewPeer(kAddress0, true);
  auto peer_1 = peer_cache()->NewPeer(kAddress1, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1));

  int conn_cb_0_count = 0;
  auto conn_cb_0 = [&](auto result) {
    ASSERT_TRUE(result.is_error());
    EXPECT_EQ(result.error(), HostError::kCanceled);
    conn_cb_0_count++;
  };

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto conn_cb_1 = [&](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
  };

  conn_mgr()->Connect(peer_0->identifier(), conn_cb_0, kConnectionOptions);
  conn_mgr()->Connect(peer_1->identifier(), conn_cb_1, kConnectionOptions);
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer_0->le()->connection_state());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer_1->le()->connection_state());

  // Do NOT wait for scanning to start asynchronously before calling Disconnect synchronously.
  // After peer_0's connection request is cancelled, peer_1's connection request should succeed.
  EXPECT_TRUE(conn_mgr()->Disconnect(peer_0->identifier()));
  RunLoopUntilIdle();
  EXPECT_EQ(conn_cb_0_count, 1);
  ASSERT_TRUE(conn_handle);
  EXPECT_EQ(conn_handle->peer_identifier(), peer_1->identifier());
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer_0->le()->connection_state());
  EXPECT_EQ(Peer::ConnectionState::kConnected, peer_1->le()->connection_state());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, DisconnectPendingConnectionDuringScan) {
  // Don't add FakePeer for peer_0 in order to stall during scanning.
  auto peer_0 = peer_cache()->NewPeer(kAddress0, true);
  auto peer_1 = peer_cache()->NewPeer(kAddress1, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1));

  int conn_cb_0_count = 0;
  auto conn_cb_0 = [&](auto result) {
    ASSERT_TRUE(result.is_error());
    EXPECT_EQ(result.error(), HostError::kCanceled);
    conn_cb_0_count++;
  };

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto conn_cb_1 = [&](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
  };

  conn_mgr()->Connect(peer_0->identifier(), conn_cb_0, kConnectionOptions);
  conn_mgr()->Connect(peer_1->identifier(), conn_cb_1, kConnectionOptions);

  // Wait for scanning to start & OnScanStart callback to be called.
  RunLoopUntilIdle();
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer_0->le()->connection_state());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer_1->le()->connection_state());

  // After peer_0's connection request is cancelled, peer_1's connection request should succeed.
  EXPECT_TRUE(conn_mgr()->Disconnect(peer_0->identifier()));
  RunLoopUntilIdle();
  EXPECT_EQ(conn_cb_0_count, 1);
  ASSERT_TRUE(conn_handle);
  EXPECT_EQ(conn_handle->peer_identifier(), peer_1->identifier());
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer_0->le()->connection_state());
  EXPECT_EQ(Peer::ConnectionState::kConnected, peer_1->le()->connection_state());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, LocalDisconnectWhileConnectorPending) {
  auto peer_0 = peer_cache()->NewPeer(kAddress0, true);
  auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0);
  fake_peer_0->set_force_pending_connect(true);
  test_device()->AddPeer(std::move(fake_peer_0));

  auto peer_1 = peer_cache()->NewPeer(kAddress1, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1));

  int conn_cb_0_count = 0;
  auto conn_cb_0 = [&](auto result) {
    EXPECT_TRUE(result.is_error());
    EXPECT_EQ(result.error(), HostError::kCanceled);
    conn_cb_0_count++;
  };

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto conn_cb_1 = [&](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
  };

  conn_mgr()->Connect(peer_0->identifier(), conn_cb_0, kConnectionOptions);
  conn_mgr()->Connect(peer_1->identifier(), conn_cb_1, kConnectionOptions);
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer_0->le()->connection_state());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer_1->le()->connection_state());

  // Wait for peer_0 scanning to complete and kLECreateConnection command to be sent.
  RunLoopUntilIdle();

  // After peer_0's connection request is cancelled, peer_1's connection request should succeed.
  EXPECT_TRUE(conn_mgr()->Disconnect(peer_0->identifier()));
  RunLoopUntilIdle();
  EXPECT_EQ(conn_cb_0_count, 1);
  ASSERT_TRUE(conn_handle);
  EXPECT_EQ(conn_handle->peer_identifier(), peer_1->identifier());
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer_0->le()->connection_state());
  EXPECT_EQ(Peer::ConnectionState::kConnected, peer_1->le()->connection_state());
}

TEST_F(GAP_LowEnergyConnectionManagerTest,
       DisconnectQueuedPendingConnectionAndThenPendingConnectionWithPendingConnector) {
  auto peer_0 = peer_cache()->NewPeer(kAddress0, true);
  auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0);
  fake_peer_0->set_force_pending_connect(true);
  test_device()->AddPeer(std::move(fake_peer_0));

  auto peer_1 = peer_cache()->NewPeer(kAddress1, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1));

  int conn_cb_0_count = 0;
  auto conn_cb_0 = [&](auto result) {
    ASSERT_TRUE(result.is_error());
    EXPECT_EQ(result.error(), HostError::kCanceled);
    conn_cb_0_count++;
  };

  int conn_cb_1_count = 0;
  auto conn_cb_1 = [&](auto result) {
    ASSERT_TRUE(result.is_error());
    EXPECT_EQ(result.error(), HostError::kCanceled);
    conn_cb_1_count++;
  };

  conn_mgr()->Connect(peer_0->identifier(), conn_cb_0, kConnectionOptions);
  conn_mgr()->Connect(peer_1->identifier(), conn_cb_1, kConnectionOptions);
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer_0->le()->connection_state());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer_1->le()->connection_state());

  EXPECT_TRUE(conn_mgr()->Disconnect(peer_1->identifier()));
  RunLoopUntilIdle();
  EXPECT_EQ(conn_cb_0_count, 0);
  EXPECT_EQ(conn_cb_1_count, 1);
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer_0->le()->connection_state());
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer_1->le()->connection_state());

  EXPECT_TRUE(conn_mgr()->Disconnect(peer_0->identifier()));
  RunLoopUntilIdle();
  EXPECT_EQ(conn_cb_0_count, 1);
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer_0->le()->connection_state());
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer_1->le()->connection_state());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, DisconnectUnknownPeer) {
  // Unknown peers are inherently "not connected."
  EXPECT_TRUE(conn_mgr()->Disconnect(PeerId(999)));
}

TEST_F(GAP_LowEnergyConnectionManagerTest, DisconnectUnconnectedPeer) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  // This returns true so long the peer is not connected.
  EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
}

TEST_F(GAP_LowEnergyConnectionManagerTest, Disconnect) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  int closed_count = 0;
  auto closed_cb = [&closed_count] { closed_count++; };

  std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
  auto success_cb = [&conn_handles, &closed_cb](auto result) {
    ASSERT_TRUE(result.is_ok());
    auto conn_handle = result.take_value();
    conn_handle->set_closed_callback(closed_cb);
    conn_handles.push_back(std::move(conn_handle));
  };

  // Issue two connection refs.
  conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
  conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);

  RunLoopUntilIdle();

  ASSERT_EQ(2u, conn_handles.size());

  EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));

  bool peer_removed = peer_cache()->RemoveDisconnectedPeer(peer->identifier());
  EXPECT_TRUE(peer_removed);

  RunLoopUntilIdle();

  EXPECT_EQ(2, closed_count);
  EXPECT_TRUE(connected_peers().empty());
  EXPECT_TRUE(canceled_peers().empty());

  // The central pause timeout handler should not run.
  RunLoopFor(kLEConnectionPauseCentral);
}

TEST_F(GAP_LowEnergyConnectionManagerTest, IntentionalDisconnectDisablesAutoConnectBehavior) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
  auto success_cb = [&conn_handles](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handles.push_back(result.take_value());
  };

  sm::PairingData data;
  data.peer_ltk = sm::LTK();
  data.local_ltk = sm::LTK();
  data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
  EXPECT_TRUE(peer_cache()->StoreLowEnergyBond(peer->identifier(), data));

  // Issue connection ref.
  conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
  RunLoopUntilIdle();

  // Bonded peer should have auto-connection enabled.
  EXPECT_TRUE(peer->le()->should_auto_connect());

  // Explicit disconnect should disable the auto-connection property.
  EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
  RunLoopUntilIdle();
  EXPECT_FALSE(peer->le()->should_auto_connect());

  // Intentional re-connection should re-enable the auto-connection property.
  conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
  RunLoopUntilIdle();
  EXPECT_TRUE(peer->le()->should_auto_connect());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, IncidentalDisconnectDoesNotAffectAutoConnectBehavior) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
  auto success_cb = [&conn_handles](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handles.push_back(result.take_value());
  };

  sm::PairingData data;
  data.peer_ltk = sm::LTK();
  data.local_ltk = sm::LTK();
  data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
  EXPECT_TRUE(peer_cache()->StoreLowEnergyBond(peer->identifier(), data));

  // Issue connection ref.
  conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
  RunLoopUntilIdle();

  // Bonded peer should have auto-connection enabled.
  EXPECT_TRUE(peer->le()->should_auto_connect());

  // Incidental disconnect should NOT disable the auto-connection property.
  ASSERT_TRUE(conn_handles.size());
  conn_handles[0] = nullptr;
  RunLoopUntilIdle();
  EXPECT_TRUE(peer->le()->should_auto_connect());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, DisconnectThrice) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  int closed_count = 0;
  auto closed_cb = [&closed_count] { closed_count++; };

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto success_cb = [&closed_cb, &conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
    ASSERT_TRUE(conn_handle);
    conn_handle->set_closed_callback(closed_cb);
  };

  conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);

  RunLoopUntilIdle();

  EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));

  // Try to disconnect again while the first disconnection is in progress.
  EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));

  RunLoopUntilIdle();

  // The single ref should get only one "closed" call.
  EXPECT_EQ(1, closed_count);
  EXPECT_TRUE(connected_peers().empty());
  EXPECT_TRUE(canceled_peers().empty());

  // Try to disconnect once more, now that the link is gone.
  EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
}

// Tests when a link is lost without explicitly disconnecting
TEST_F(GAP_LowEnergyConnectionManagerTest, DisconnectEvent) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);

  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  int closed_count = 0;
  auto closed_cb = [&closed_count] { closed_count++; };

  std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
  auto success_cb = [&conn_handles, &closed_cb](auto result) {
    ASSERT_TRUE(result.is_ok());
    auto conn_handle = result.take_value();
    conn_handle->set_closed_callback(closed_cb);
    conn_handles.push_back(std::move(conn_handle));
  };

  // Issue two connection refs.
  conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
  conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);

  RunLoopUntilIdle();

  ASSERT_EQ(2u, conn_handles.size());

  // This makes FakeController send us HCI Disconnection Complete events.
  test_device()->Disconnect(kAddress0);

  RunLoopUntilIdle();

  EXPECT_EQ(2, closed_count);
}

TEST_F(GAP_LowEnergyConnectionManagerTest, DisconnectAfterRefsReleased) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto success_cb = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
  };

  conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);

  RunLoopUntilIdle();

  ASSERT_TRUE(conn_handle);
  conn_handle.reset();

  // Try to disconnect while the zero-refs connection is being disconnected.
  EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));

  RunLoopUntilIdle();

  EXPECT_TRUE(connected_peers().empty());
  EXPECT_TRUE(canceled_peers().empty());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, DisconnectAfterSecondConnectionRequestInvalidatesRefs) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle_0;
  auto success_cb = [&conn_handle_0](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle_0 = result.take_value();
    ASSERT_TRUE(conn_handle_0);
    EXPECT_TRUE(conn_handle_0->active());
  };

  conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
  RunLoopUntilIdle();
  ASSERT_TRUE(conn_handle_0);
  EXPECT_TRUE(conn_handle_0->active());

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle_1;
  auto ref_cb = [&conn_handle_1](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle_1 = result.take_value();
  };

  // Callback should be run synchronously with success status because connection already exists.
  conn_mgr()->Connect(peer->identifier(), ref_cb, kConnectionOptions);
  EXPECT_TRUE(conn_handle_1);
  EXPECT_TRUE(conn_handle_1->active());

  // This should invalidate the refs.
  EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
  EXPECT_FALSE(conn_handle_1->active());
  EXPECT_FALSE(conn_handle_0->active());

  RunLoopUntilIdle();
}

// This tests that a connection reference callback succeeds if a HCI
// Disconnection Complete event is received for the corresponding ACL link
// immediately after the callback gets run.
TEST_F(GAP_LowEnergyConnectionManagerTest, DisconnectCompleteEventAfterConnect) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto success_cb = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
    EXPECT_TRUE(conn_handle->active());
  };

  conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
  RunLoopUntilIdle();
  ASSERT_TRUE(conn_handle);

  // Request a new reference. Disconnect the link before the reference is
  // received.
  size_t ref_cb_count = 0;
  auto ref_cb = [&ref_cb_count](auto result) {
    ref_cb_count++;
    EXPECT_TRUE(result.is_ok());
  };

  size_t disconn_cb_count = 0;
  auto disconn_cb = [this, ref_cb, peer, &disconn_cb_count, &ref_cb_count](auto) {
    disconn_cb_count++;
    // The link is gone but conn_mgr() hasn't updated the connection state yet.
    // The request to connect will attempt to add a new reference which will succeed because ref_cb
    // is called synchronously.
    EXPECT_EQ(0u, ref_cb_count);
    conn_mgr()->Connect(peer->identifier(), ref_cb, kConnectionOptions);
    EXPECT_EQ(1u, ref_cb_count);
  };
  conn_mgr()->SetDisconnectCallbackForTesting(disconn_cb);

  test_device()->SendDisconnectionCompleteEvent(conn_handle->handle());

  RunLoopUntilIdle();

  EXPECT_EQ(1u, ref_cb_count);
  EXPECT_EQ(1u, disconn_cb_count);
}

TEST_F(GAP_LowEnergyConnectionManagerTest, RemovePeerFromPeerCacheDuringDisconnection) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto success_cb = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
    EXPECT_TRUE(conn_handle->active());
  };

  conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
  RunLoopUntilIdle();
  ASSERT_TRUE(conn_handle);

  // This should invalidate the ref that was bound to |ref_cb|.
  const PeerId id = peer->identifier();
  EXPECT_TRUE(conn_mgr()->Disconnect(id));
  ASSERT_FALSE(peer->le()->connected());
  EXPECT_FALSE(conn_handle->active());

  EXPECT_TRUE(peer_cache()->RemoveDisconnectedPeer(id));

  RunLoopUntilIdle();

  EXPECT_FALSE(peer_cache()->FindById(id));
  EXPECT_FALSE(peer_cache()->FindByAddress(kAddress0));
}

// Listener receives remote initiated connection ref.
TEST_F(GAP_LowEnergyConnectionManagerTest, RegisterRemoteInitiatedLink) {
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  // First create a fake incoming connection.
  test_device()->ConnectLowEnergy(kAddress0);

  RunLoopUntilIdle();

  auto link = MoveLastRemoteInitiated();
  ASSERT_TRUE(link);

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  conn_mgr()->RegisterRemoteInitiatedLink(std::move(link), BondableMode::Bondable,
                                          [&](auto result) {
                                            ASSERT_TRUE(result.is_ok());
                                            conn_handle = result.take_value();
                                          });
  // A Peer should now exist in the cache.
  auto* peer = peer_cache()->FindByAddress(kAddress0);
  EXPECT_EQ(peer->le()->connection_state(), Peer::ConnectionState::kInitializing);

  RunLoopUntilIdle();

  ASSERT_TRUE(conn_handle);
  EXPECT_TRUE(conn_handle->active());
  ASSERT_TRUE(peer);
  EXPECT_EQ(peer->identifier(), conn_handle->peer_identifier());
  EXPECT_TRUE(peer->connected());
  EXPECT_TRUE(peer->le()->connected());
  EXPECT_TRUE(peer->version().has_value());
  EXPECT_TRUE(peer->le()->features().has_value());

  conn_handle = nullptr;

  RunLoopUntilIdle();
  EXPECT_TRUE(connected_peers().empty());
}

TEST_F(GAP_LowEnergyConnectionManagerTest,
       RegisterRemoteInitiatedLinkDuringLocalInitiatedLinkConnecting) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  fake_peer->set_force_pending_connect(true);
  test_device()->AddPeer(std::move(fake_peer));

  // Create a fake incoming connection.
  test_device()->ConnectLowEnergy(kAddress0);
  RunLoopUntilIdle();
  auto link = MoveLastRemoteInitiated();
  ASSERT_TRUE(link);

  // Create a pending outgoing connection.
  ConnectionResult result;
  auto callback = [&result](auto res) { result = std::move(res); };
  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  conn_mgr()->RegisterRemoteInitiatedLink(std::move(link), BondableMode::Bondable,
                                          [&](auto result) {
                                            ASSERT_TRUE(result.is_ok());
                                            conn_handle = result.take_value();
                                          });
  RunLoopUntilIdle();
  ASSERT_TRUE(conn_handle);

  // Local connector result handler should not crash when it finds that connection to peer already
  // exists.
  RunLoopFor(kLECreateConnectionTimeout);
  // An error should be returned if the connection complete was incorrectly not matched to the
  // pending connection request (see fxbug.dev/68969).
  // In the future it may make sense to return success because a link to the peer already exists.
  ASSERT_TRUE(result.is_error());
  EXPECT_TRUE(peer->le()->connected());
}

TEST_F(GAP_LowEnergyConnectionManagerTest,
       RegisterRemoteInitiatedLinkDuringLocalInitiatedConnectionScanning) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  fake_peer->set_advertising_enabled(false);
  test_device()->AddPeer(std::move(fake_peer));

  // Create a fake incoming connection.
  test_device()->ConnectLowEnergy(kAddress0);
  RunLoopUntilIdle();
  auto link = MoveLastRemoteInitiated();
  ASSERT_TRUE(link);

  // Create a pending outgoing connection.
  ConnectionResult result;
  auto callback = [&result](auto res) { result = std::move(res); };
  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  conn_mgr()->RegisterRemoteInitiatedLink(std::move(link), BondableMode::Bondable,
                                          [&](auto result) {
                                            ASSERT_TRUE(result.is_ok());
                                            conn_handle = result.take_value();
                                          });
  RunLoopUntilIdle();
  ASSERT_TRUE(conn_handle);

  // Local connector result handler should not crash when it finds that connection to peer already
  // exists.
  RunLoopFor(kLEGeneralCepScanTimeout);
  ASSERT_TRUE(result.is_error());
  EXPECT_TRUE(peer->le()->connected());
}

// Listener receives remote initiated connection ref for a known peer with the
// same BR/EDR address.
TEST_F(GAP_LowEnergyConnectionManagerTest, IncomingConnectionUpgradesKnownBrEdrPeerToDualMode) {
  Peer* peer = peer_cache()->NewPeer(kAddrAlias0, true);
  ASSERT_TRUE(peer);
  ASSERT_EQ(peer, peer_cache()->FindByAddress(kAddress0));
  ASSERT_EQ(TechnologyType::kClassic, peer->technology());

  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  // First create a fake incoming connection.
  test_device()->ConnectLowEnergy(kAddress0);

  RunLoopUntilIdle();

  auto link = MoveLastRemoteInitiated();
  ASSERT_TRUE(link);

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  conn_mgr()->RegisterRemoteInitiatedLink(std::move(link), BondableMode::Bondable,
                                          [&conn_handle](auto result) {
                                            ASSERT_TRUE(result.is_ok());
                                            conn_handle = result.take_value();
                                          });
  RunLoopUntilIdle();
  ASSERT_TRUE(conn_handle);

  EXPECT_EQ(peer->identifier(), conn_handle->peer_identifier());
  EXPECT_EQ(TechnologyType::kDualMode, peer->technology());
}

// Successful connection to a peer whose address type is kBREDR.
// TODO(fxbug.dev/2761): This test will likely become obsolete when LE connections are based on the
// presence of LowEnergyData in a Peer and no address type enum exists.
TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectAndDisconnectDualModeDeviceWithBrEdrAddress) {
  Peer* peer = peer_cache()->NewPeer(kAddrAlias0, true);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(peer->bredr());

  peer->MutLe();
  ASSERT_EQ(TechnologyType::kDualMode, peer->technology());
  ASSERT_EQ(peer, peer_cache()->FindByAddress(kAddress0));
  ASSERT_EQ(DeviceAddress::Type::kBREDR, peer->address().type());

  // Only the LE transport connects in this test, so only add an LE FakePeer to FakeController.
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto callback = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
  };

  EXPECT_TRUE(connected_peers().empty());
  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

  RunLoopUntilIdle();

  EXPECT_EQ(1u, connected_peers().size());
  EXPECT_EQ(1u, connected_peers().count(kAddress0));

  ASSERT_TRUE(conn_handle);
  EXPECT_TRUE(conn_handle->active());
  EXPECT_EQ(peer->identifier(), conn_handle->peer_identifier());
  EXPECT_FALSE(peer->temporary());
  EXPECT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());

  conn_handle = nullptr;
  RunLoopUntilIdle();
  EXPECT_EQ(0u, connected_peers().size());
}

// Tests that the central accepts the connection parameters that are sent from
// a fake peripheral and eventually applies them to the link.
TEST_F(GAP_LowEnergyConnectionManagerTest,
       CentralAppliesL2capConnectionParameterUpdateRequestParams) {
  // Set up a fake peer and a connection over which to process the L2CAP
  // request.
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  ASSERT_TRUE(peer);

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto conn_cb = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
  };
  conn_mgr()->Connect(peer->identifier(), conn_cb, kConnectionOptions);

  RunLoopUntilIdle();
  ASSERT_TRUE(conn_handle);

  hci::LEPreferredConnectionParameters preferred(
      hci::kLEConnectionIntervalMin, hci::kLEConnectionIntervalMax, hci::kLEConnectionLatencyMax,
      hci::kLEConnectionSupervisionTimeoutMax);

  std::optional<hci::LEConnectionParameters> actual;

  auto conn_params_updated_cb = [&](const auto& addr, const auto& params) { actual = params; };
  test_device()->set_le_connection_parameters_callback(conn_params_updated_cb);

  fake_l2cap()->TriggerLEConnectionParameterUpdate(conn_handle->handle(), preferred);

  // These connection update events for the wrong handle should be ignored.
  // Send twice: once before the parameter request is processed, and once after the request has been
  // processed.
  hci::LEConnectionParameters wrong_handle_conn_params(0, 1, 2);
  test_device()->SendLEConnectionUpdateCompleteSubevent(conn_handle->handle() + 1,
                                                        wrong_handle_conn_params);
  RunLoopUntilIdle();

  test_device()->SendLEConnectionUpdateCompleteSubevent(conn_handle->handle() + 1,
                                                        wrong_handle_conn_params);

  RunLoopUntilIdle();

  ASSERT_TRUE(actual.has_value());
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(preferred, *peer->le()->preferred_connection_parameters());
  EXPECT_EQ(actual.value(), *peer->le()->connection_parameters());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, L2CAPSignalLinkError) {
  // Set up a fake peer and a connection over which to process the L2CAP
  // request.
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  ASSERT_TRUE(peer);

  fbl::RefPtr<l2cap::Channel> att_chan;
  auto l2cap_chan_cb = [&att_chan](auto chan) { att_chan = chan; };
  fake_l2cap()->set_channel_callback(l2cap_chan_cb);

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto conn_cb = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
  };
  conn_mgr()->Connect(peer->identifier(), conn_cb, kConnectionOptions);

  RunLoopUntilIdle();
  ASSERT_TRUE(conn_handle);
  ASSERT_TRUE(att_chan);
  ASSERT_EQ(1u, connected_peers().size());

  // Signaling a link error through the channel should disconnect the link.
  att_chan->SignalLinkError();

  RunLoopUntilIdle();
  EXPECT_TRUE(connected_peers().empty());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, PairUnconnectedPeer) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  EXPECT_TRUE(peer->temporary());
  ASSERT_EQ(peer_cache()->count(), 1u);
  uint count_cb_called = 0;
  auto cb = [&count_cb_called](sm::Status status) {
    ASSERT_EQ(status.error(), bt::HostError::kNotFound);
    count_cb_called++;
  };
  conn_mgr()->Pair(peer->identifier(), sm::SecurityLevel::kEncrypted, sm::BondableMode::Bondable,
                   cb);
  ASSERT_EQ(count_cb_called, 1u);
}

TEST_F(GAP_LowEnergyConnectionManagerTest, PairWithBondableModes) {
  // clang-format on
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto callback = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
    EXPECT_TRUE(conn_handle);
    EXPECT_TRUE(conn_handle->active());
  };

  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  ASSERT_TRUE(peer->le());

  RunLoopUntilIdle();
  fxl::WeakPtr<TestSm> mock_sm = TestSmByHandle(conn_handle->handle());
  ASSERT_TRUE(mock_sm);

  ASSERT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());

  EXPECT_FALSE(mock_sm->last_requested_upgrade().has_value());
  conn_mgr()->Pair(peer->identifier(), sm::SecurityLevel::kEncrypted, sm::BondableMode::Bondable,
                   [](sm::Status cb_status) {});
  RunLoopUntilIdle();

  EXPECT_EQ(BondableMode::Bondable, mock_sm->bondable_mode());
  EXPECT_EQ(sm::SecurityLevel::kEncrypted, mock_sm->last_requested_upgrade());

  conn_mgr()->Pair(peer->identifier(), sm::SecurityLevel::kAuthenticated,
                   sm::BondableMode::NonBondable, [](sm::Status cb_status) {});
  RunLoopUntilIdle();

  EXPECT_EQ(BondableMode::NonBondable, mock_sm->bondable_mode());
  EXPECT_EQ(sm::SecurityLevel::kAuthenticated, mock_sm->last_requested_upgrade());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectAndDiscoverByServiceWithoutUUID) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);

  bool cb_called = false;
  auto expect_uuids = [&cb_called](PeerId peer_id, auto uuids) {
    ASSERT_TRUE(uuids.empty());
    cb_called = true;
  };
  fake_gatt()->SetDiscoverServicesCallback(expect_uuids);

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto callback = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
    EXPECT_TRUE(conn_handle);
    EXPECT_TRUE(conn_handle->active());
  };

  LowEnergyConnectionOptions connection_options{.service_uuid = std::nullopt};
  conn_mgr()->Connect(peer->identifier(), callback, connection_options);

  RunLoopUntilIdle();

  ASSERT_TRUE(cb_called);
}

TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectAndDiscoverByServiceUuid) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);

  UUID kConnectUuid({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15});
  std::array<UUID, 2> expected_uuids = {kConnectUuid, kGenericAccessService};

  bool cb_called = false;
  auto expect_uuid = [&cb_called, expected_uuids](PeerId peer_id, auto uuids) {
    EXPECT_THAT(uuids, ::testing::UnorderedElementsAreArray(expected_uuids));
    cb_called = true;
  };
  fake_gatt()->SetDiscoverServicesCallback(expect_uuid);

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto callback = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
    ASSERT_TRUE(conn_handle);
    EXPECT_TRUE(conn_handle->active());
  };

  LowEnergyConnectionOptions connection_options{.service_uuid = std::optional(kConnectUuid)};
  conn_mgr()->Connect(peer->identifier(), callback, connection_options);

  RunLoopUntilIdle();

  ASSERT_TRUE(cb_called);
}

TEST_F(GAP_LowEnergyConnectionManagerTest,
       ReadPeripheralPreferredConnectionParametersCharacteristicAndUpdateConnectionParameters) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  // Set up GAP service
  gatt::ServiceData service_data(gatt::ServiceKind::PRIMARY, /*start=*/0x0001, /*end=*/0x0009,
                                 kGenericAccessService);
  auto [remote_svc, service_client] = fake_gatt()->AddPeerService(peer->identifier(), service_data);

  // Set up preferred connection parameters characteristic.
  att::Handle char_handle = 0x0002;
  att::Handle char_value_handle = 0x0003;
  gatt::CharacteristicData char_data(gatt::kRead, /*ext_props=*/std::nullopt, char_handle,
                                     char_value_handle,
                                     kPeripheralPreferredConnectionParametersCharacteristic);
  service_client->set_characteristics({char_data});
  StaticByteBuffer char_value(0x01, 0x00,   // min interval
                              0x02, 0x00,   // max interval
                              0x03, 0x00,   // max latency
                              0x04, 0x00);  // supervision timeout
  service_client->set_read_request_callback(
      [char_value_handle, char_value](att::Handle handle, auto read_cb) {
        if (handle == char_value_handle) {
          read_cb(att::Status(), char_value);
        }
      });

  std::unique_ptr<LowEnergyConnectionHandle> conn_ref;
  auto callback = [&conn_ref](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_ref = result.take_value();
  };

  conn_mgr()->Connect(peer->identifier(), callback, LowEnergyConnectionOptions());

  RunLoopUntilIdle();
  EXPECT_TRUE(conn_ref);
  ASSERT_TRUE(peer->le()->preferred_connection_parameters());
  auto params = peer->le()->preferred_connection_parameters().value();
  EXPECT_EQ(params.min_interval(), 1u);
  EXPECT_EQ(params.max_interval(), 2u);
  EXPECT_EQ(params.max_latency(), 3u);
  EXPECT_EQ(params.supervision_timeout(), 4u);

  std::optional<hci::LEConnectionParameters> conn_params;
  test_device()->set_le_connection_parameters_callback(
      [&](auto address, auto parameters) { conn_params = parameters; });

  RunLoopFor(kLEConnectionPauseCentral);
  ASSERT_TRUE(conn_params.has_value());
  EXPECT_EQ(conn_params->interval(), 1u);  // FakeController will use min interval
  EXPECT_EQ(conn_params->latency(), 3u);
  EXPECT_EQ(conn_params->supervision_timeout(), 4u);
}

TEST_F(GAP_LowEnergyConnectionManagerTest,
       ReadPeripheralPreferredConnectionParametersCharacteristicInvalidValueSize) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  // Set up GAP service
  gatt::ServiceData service_data(gatt::ServiceKind::PRIMARY, /*start=*/0x0001, /*end=*/0x0003,
                                 kGenericAccessService);
  auto [remote_svc, service_client] = fake_gatt()->AddPeerService(peer->identifier(), service_data);

  // Set up preferred connection parameters characteristic.
  att::Handle char_handle = 0x0002;
  att::Handle char_value_handle = 0x0003;
  gatt::CharacteristicData char_data(gatt::kRead, /*ext_props=*/std::nullopt, char_handle,
                                     char_value_handle,
                                     kPeripheralPreferredConnectionParametersCharacteristic);
  service_client->set_characteristics({char_data});
  StaticByteBuffer invalid_char_value(0x01);  // too small
  service_client->set_read_request_callback(
      [char_value_handle, invalid_char_value](auto handle, auto read_cb) {
        if (handle == char_value_handle) {
          read_cb(att::Status(), invalid_char_value);
        }
      });

  std::unique_ptr<LowEnergyConnectionHandle> conn_ref;
  auto callback = [&conn_ref](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_ref = result.take_value();
  };

  conn_mgr()->Connect(peer->identifier(), callback, LowEnergyConnectionOptions());

  RunLoopUntilIdle();
  EXPECT_TRUE(conn_ref);
  EXPECT_FALSE(peer->le()->preferred_connection_parameters());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, GapServiceCharacteristicDiscoveryError) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  // Set up GAP service
  gatt::ServiceData service_data(gatt::ServiceKind::PRIMARY, /*start=*/0x0001, /*end=*/0x0003,
                                 kGenericAccessService);
  auto [remote_svc, service_client] = fake_gatt()->AddPeerService(peer->identifier(), service_data);

  // Set up preferred connection parameters characteristic.
  att::Handle char_handle = 0x0002;
  att::Handle char_value_handle = 0x0003;
  gatt::CharacteristicData char_data(gatt::kRead, /*ext_props=*/std::nullopt, char_handle,
                                     char_value_handle,
                                     kPeripheralPreferredConnectionParametersCharacteristic);
  service_client->set_characteristic_discovery_status(
      att::Status(att::ErrorCode::kReadNotPermitted));

  std::unique_ptr<LowEnergyConnectionHandle> conn_ref;
  auto callback = [&conn_ref](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_ref = result.take_value();
  };

  conn_mgr()->Connect(peer->identifier(), callback, LowEnergyConnectionOptions());

  RunLoopUntilIdle();
  EXPECT_TRUE(conn_ref);
  EXPECT_FALSE(peer->le()->preferred_connection_parameters());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, GapServiceListServicesError) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  fake_gatt()->set_list_services_status(att::Status(HostError::kFailed));

  std::unique_ptr<LowEnergyConnectionHandle> conn_ref;
  auto callback = [&conn_ref](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_ref = result.take_value();
  };

  conn_mgr()->Connect(peer->identifier(), callback, LowEnergyConnectionOptions());

  RunLoopUntilIdle();
  EXPECT_TRUE(conn_ref);
  EXPECT_FALSE(peer->le()->preferred_connection_parameters());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, PeerGapServiceMissingConnectionParameterCharacteristic) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  // Set up GAP service
  gatt::ServiceData service_data(gatt::ServiceKind::PRIMARY, /*start=*/0x0001, /*end=*/0x0003,
                                 kGenericAccessService);
  auto [remote_svc, service_client] = fake_gatt()->AddPeerService(peer->identifier(), service_data);

  std::unique_ptr<LowEnergyConnectionHandle> conn_ref;
  auto callback = [&conn_ref](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_ref = result.take_value();
  };

  conn_mgr()->Connect(peer->identifier(), callback, LowEnergyConnectionOptions());

  RunLoopUntilIdle();
  EXPECT_TRUE(conn_ref);
  EXPECT_FALSE(peer->le()->preferred_connection_parameters());
}

// Listener receives remote initiated connection ref.
TEST_F(GAP_LowEnergyConnectionManagerTest, PassBondableThroughRemoteInitiatedLink) {
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  // First create a fake incoming connection.
  test_device()->ConnectLowEnergy(kAddress0);

  RunLoopUntilIdle();

  auto link = MoveLastRemoteInitiated();
  ASSERT_TRUE(link);

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  conn_mgr()->RegisterRemoteInitiatedLink(std::move(link), BondableMode::Bondable,
                                          [&conn_handle](auto result) {
                                            ASSERT_TRUE(result.is_ok());
                                            conn_handle = result.take_value();
                                          });
  RunLoopUntilIdle();

  ASSERT_TRUE(conn_handle);
  EXPECT_TRUE(conn_handle->active());
  EXPECT_EQ(conn_handle->bondable_mode(), BondableMode::Bondable);
}

TEST_F(GAP_LowEnergyConnectionManagerTest, PassNonBondableThroughRemoteInitiatedLink) {
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  // First create a fake incoming connection.
  test_device()->ConnectLowEnergy(kAddress0);

  RunLoopUntilIdle();

  auto link = MoveLastRemoteInitiated();
  ASSERT_TRUE(link);

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  conn_mgr()->RegisterRemoteInitiatedLink(std::move(link), BondableMode::NonBondable,
                                          [&conn_handle](auto result) {
                                            ASSERT_TRUE(result.is_ok());
                                            conn_handle = result.take_value();
                                          });
  RunLoopUntilIdle();

  ASSERT_TRUE(conn_handle);
  EXPECT_TRUE(conn_handle->active());
  EXPECT_EQ(conn_handle->bondable_mode(), BondableMode::NonBondable);
}

// Successful connection to single peer
TEST_F(GAP_LowEnergyConnectionManagerTest, PassBondableThroughConnect) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto callback = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
    ASSERT_TRUE(conn_handle);
    EXPECT_TRUE(conn_handle->active());
  };

  EXPECT_TRUE(connected_peers().empty());
  conn_mgr()->Connect(peer->identifier(), callback, {.bondable_mode = BondableMode::Bondable});

  RunLoopUntilIdle();

  ASSERT_TRUE(conn_handle);
  EXPECT_EQ(conn_handle->bondable_mode(), BondableMode::Bondable);
}

// Successful connection to single peer
TEST_F(GAP_LowEnergyConnectionManagerTest, PassNonBondableThroughConnect) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto callback = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
    ASSERT_TRUE(conn_handle);
    EXPECT_TRUE(conn_handle->active());
  };

  EXPECT_TRUE(connected_peers().empty());
  conn_mgr()->Connect(peer->identifier(), callback, {.bondable_mode = BondableMode::NonBondable});

  RunLoopUntilIdle();

  ASSERT_TRUE(conn_handle);
  EXPECT_EQ(conn_handle->bondable_mode(), BondableMode::NonBondable);
}

// Tests that the connection manager cleans up its connection map correctly following a
// disconnection due to encryption failure.
TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectionCleanUpFollowingEncryptionFailure) {
  // Set up a connection.
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  std::unique_ptr<LowEnergyConnectionHandle> conn;
  conn_mgr()->Connect(
      peer->identifier(),
      [&](auto result) {
        ASSERT_TRUE(result.is_ok());
        conn = result.take_value();
      },
      kConnectionOptions);
  RunLoopUntilIdle();
  ASSERT_TRUE(conn);

  hci::ConnectionHandle handle = conn->handle();
  bool ref_cleaned_up = false;
  bool disconnected = false;
  conn->set_closed_callback([&] { ref_cleaned_up = true; });
  conn_mgr()->SetDisconnectCallbackForTesting([&](hci::ConnectionHandle cb_handle) {
    EXPECT_EQ(handle, cb_handle);
    disconnected = true;
  });

  test_device()->SendEncryptionChangeEvent(handle, hci::StatusCode::kConnectionTerminatedMICFailure,
                                           hci::EncryptionStatus::kOff);
  test_device()->SendDisconnectionCompleteEvent(handle);
  RunLoopUntilIdle();

  EXPECT_TRUE(ref_cleaned_up);
  EXPECT_TRUE(disconnected);
}

TEST_F(GAP_LowEnergyConnectionManagerTest, SuccessfulInterrogationSetsPeerVersionAndFeatures) {
  constexpr hci::LESupportedFeatures kLEFeatures{
      static_cast<uint64_t>(hci::LESupportedFeature::kConnectionParametersRequestProcedure)};

  // Set up a connection.
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  ASSERT_TRUE(peer->le());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  fake_peer->set_le_features(kLEFeatures);
  test_device()->AddPeer(std::move(fake_peer));

  std::unique_ptr<LowEnergyConnectionHandle> conn;
  conn_mgr()->Connect(
      peer->identifier(),
      [&](auto result) {
        ASSERT_TRUE(result.is_ok());
        conn = result.take_value();
      },
      kConnectionOptions);

  EXPECT_FALSE(peer->version().has_value());
  EXPECT_FALSE(peer->le()->features().has_value());
  RunLoopUntilIdle();
  EXPECT_TRUE(conn);
  EXPECT_TRUE(peer->version().has_value());
  EXPECT_TRUE(peer->le()->features().has_value());
  EXPECT_EQ(kLEFeatures.le_features, peer->le()->features()->le_features);
  EXPECT_FALSE(peer->temporary());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectInterrogationFailure) {
  // Set up a connection.
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  ASSERT_TRUE(peer->le());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  std::optional<HostError> error;
  conn_mgr()->Connect(
      peer->identifier(),
      [&](auto result) {
        ASSERT_TRUE(result.is_error());
        error = result.error();
      },
      kConnectionOptions);
  ASSERT_FALSE(peer->le()->features().has_value());

  // Remove fake peer so LE Read Remote Features command fails during interrogation.
  test_device()->set_le_read_remote_features_callback(
      [this]() { test_device()->RemovePeer(kAddress0); });

  RunLoopUntilIdle();
  ASSERT_TRUE(error.has_value());
  EXPECT_FALSE(peer->connected());
  EXPECT_FALSE(peer->le()->connected());
  EXPECT_FALSE(peer->temporary());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, RemoteInitiatedLinkInterrogationFailure) {
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  // First create a fake incoming connection.
  test_device()->ConnectLowEnergy(kAddress0);

  RunLoopUntilIdle();

  auto link = MoveLastRemoteInitiated();
  ASSERT_TRUE(link);

  std::optional<HostError> error;
  conn_mgr()->RegisterRemoteInitiatedLink(std::move(link), BondableMode::Bondable,
                                          [&](auto result) {
                                            ASSERT_TRUE(result.is_error());
                                            error = result.error();
                                          });

  // Remove fake peer so LE Read Remote Features command fails during interrogation.
  test_device()->set_le_read_remote_features_callback(
      [this]() { test_device()->RemovePeer(kAddress0); });

  RunLoopUntilIdle();
  ASSERT_TRUE(error.has_value());

  // A Peer should now exist in the cache.
  auto* peer = peer_cache()->FindByAddress(kAddress0);
  ASSERT_TRUE(peer);
  EXPECT_FALSE(peer->connected());
  EXPECT_FALSE(peer->le()->connected());
  EXPECT_FALSE(peer->temporary());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, L2capRequestConnParamUpdateAfterInterrogation) {
  const hci::LEPreferredConnectionParameters kConnParams(
      hci::defaults::kLEConnectionIntervalMin, hci::defaults::kLEConnectionIntervalMax,
      /*max_latency=*/0, hci::defaults::kLESupervisionTimeout);

  // Connection Parameter Update procedure NOT supported.
  constexpr hci::LESupportedFeatures kLEFeatures{0};
  auto peer = std::make_unique<FakePeer>(kAddress0);
  peer->set_le_features(kLEFeatures);
  test_device()->AddPeer(std::move(peer));

  // First create a fake incoming connection as peripheral.
  test_device()->ConnectLowEnergy(kAddress0, hci::ConnectionRole::kSlave);

  RunLoopUntilIdle();

  auto link = MoveLastRemoteInitiated();
  ASSERT_TRUE(link);

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  conn_mgr()->RegisterRemoteInitiatedLink(std::move(link), BondableMode::Bondable,
                                          [&](auto result) {
                                            ASSERT_TRUE(result.is_ok());
                                            conn_handle = result.take_value();
                                          });

  size_t l2cap_conn_param_update_count = 0;
  fake_l2cap()->set_connection_parameter_update_request_responder([&](auto handle, auto params) {
    EXPECT_EQ(kConnParams, params);
    l2cap_conn_param_update_count++;
    return true;
  });

  size_t hci_update_conn_param_count = 0;
  test_device()->set_le_connection_parameters_callback(
      [&](auto address, auto parameters) { hci_update_conn_param_count++; });

  RunLoopUntilIdle();
  ASSERT_TRUE(conn_handle);
  EXPECT_TRUE(conn_handle->active());
  EXPECT_EQ(0u, l2cap_conn_param_update_count);
  EXPECT_EQ(0u, hci_update_conn_param_count);

  RunLoopFor(kLEConnectionPausePeripheral);
  EXPECT_EQ(1u, l2cap_conn_param_update_count);
  EXPECT_EQ(0u, hci_update_conn_param_count);
}

// Based on PTS L2CAP/LE/CPU/BV-01-C, in which the LE feature mask indicates support for the
// Connection Parameter Request Procedure, but sending the request results in a
// kUnsupportedRemoteFeature event status. PTS expects the host to retry with a L2cap connection
// parameter request.
//
// Test that this behavior is followed for 2 concurrent connections in order to ensure correct
// command/event handling.
TEST_F(GAP_LowEnergyConnectionManagerTest, PeripheralsRetryLLConnectionUpdateWithL2capRequest) {
  auto peer0 = std::make_unique<FakePeer>(kAddress0);
  auto peer1 = std::make_unique<FakePeer>(kAddress1);

  // Connection Parameter Update procedure supported by controller.
  constexpr hci::LESupportedFeatures kLEFeatures{
      static_cast<uint64_t>(hci::LESupportedFeature::kConnectionParametersRequestProcedure)};

  peer0->set_le_features(kLEFeatures);
  peer1->set_le_features(kLEFeatures);

  // Simulate host rejection by causing FakeController to set LE Connection Update Complete status
  // to kUnsupportedRemoteFeature, as PTS does.
  peer0->set_supports_ll_conn_update_procedure(false);
  peer1->set_supports_ll_conn_update_procedure(false);

  test_device()->AddPeer(std::move(peer0));
  test_device()->AddPeer(std::move(peer1));

  // First create fake incoming connections with local host as peripheral.
  test_device()->ConnectLowEnergy(kAddress0, hci::ConnectionRole::kSlave);
  RunLoopUntilIdle();
  auto link0 = MoveLastRemoteInitiated();
  ASSERT_TRUE(link0);

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle0;
  conn_mgr()->RegisterRemoteInitiatedLink(std::move(link0), BondableMode::Bondable,
                                          [&](auto result) {
                                            ASSERT_TRUE(result.is_ok());
                                            conn_handle0 = result.take_value();
                                          });

  test_device()->ConnectLowEnergy(kAddress1, hci::ConnectionRole::kSlave);
  RunLoopUntilIdle();
  auto link1 = MoveLastRemoteInitiated();
  ASSERT_TRUE(link1);

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle1;
  conn_mgr()->RegisterRemoteInitiatedLink(std::move(link1), BondableMode::Bondable,
                                          [&](auto result) {
                                            ASSERT_TRUE(result.is_ok());
                                            conn_handle1 = result.take_value();
                                          });

  size_t l2cap_conn_param_update_count = 0;
  size_t hci_update_conn_param_count = 0;

  fake_l2cap()->set_connection_parameter_update_request_responder([&](auto handle, auto params) {
    switch (l2cap_conn_param_update_count) {
      case 0:
        EXPECT_EQ(handle, conn_handle0->handle());
        break;
      case 1:
        EXPECT_EQ(handle, conn_handle1->handle());
        break;
      default:
        ADD_FAILURE();
    }

    // connection update commands should be sent before l2cap requests
    EXPECT_EQ(2u, hci_update_conn_param_count);

    l2cap_conn_param_update_count++;
    return true;
  });

  test_device()->set_le_connection_parameters_callback([&](auto address, auto params) {
    switch (hci_update_conn_param_count) {
      case 0:
        EXPECT_EQ(address, kAddress0);
        break;
      case 1:
        EXPECT_EQ(address, kAddress1);
        break;
      default:
        ADD_FAILURE();
    }

    // l2cap requests should not be sent until after failed HCI connection update commands
    EXPECT_EQ(0u, l2cap_conn_param_update_count);

    hci_update_conn_param_count++;
  });

  RunLoopFor(kLEConnectionPausePeripheral);
  ASSERT_TRUE(conn_handle0);
  EXPECT_TRUE(conn_handle0->active());
  ASSERT_TRUE(conn_handle1);
  EXPECT_TRUE(conn_handle1->active());

  EXPECT_EQ(2u, hci_update_conn_param_count);
  EXPECT_EQ(2u, l2cap_conn_param_update_count);

  // l2cap requests should not be sent on subsequent events
  test_device()->SendLEConnectionUpdateCompleteSubevent(conn_handle1->handle(),
                                                        hci::LEConnectionParameters(),
                                                        hci::StatusCode::kUnsupportedRemoteFeature);
  RunLoopUntilIdle();
  EXPECT_EQ(2u, l2cap_conn_param_update_count);
}

// Based on PTS L2CAP/LE/CPU/BV-01-C. When run twice, the controller caches the LE Connection
// Update Complete kUnsupportedRemoteFeature status and returns it directly in future LE
// Connection Update Command Status events. The host should retry with the L2CAP Connection
// Parameter Update Request after receiving this kUnsupportedRemoteFeature command status.
TEST_F(GAP_LowEnergyConnectionManagerTest,
       PeripheralSendsL2capConnParamReqAfterConnUpdateCommandStatusUnsupportedRemoteFeature) {
  auto peer = std::make_unique<FakePeer>(kAddress0);

  // Connection Parameter Update procedure supported by controller.
  constexpr hci::LESupportedFeatures kLEFeatures{
      static_cast<uint64_t>(hci::LESupportedFeature::kConnectionParametersRequestProcedure)};
  peer->set_le_features(kLEFeatures);
  test_device()->AddPeer(std::move(peer));

  // First create a fake incoming connection with local host as peripheral.
  test_device()->ConnectLowEnergy(kAddress0, hci::ConnectionRole::kSlave);
  RunLoopUntilIdle();

  auto link = MoveLastRemoteInitiated();
  ASSERT_TRUE(link);

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  conn_mgr()->RegisterRemoteInitiatedLink(std::move(link), BondableMode::Bondable,
                                          [&](auto result) {
                                            ASSERT_TRUE(result.is_ok());
                                            conn_handle = result.take_value();
                                          });

  size_t l2cap_conn_param_update_count = 0;
  size_t hci_update_conn_param_count = 0;

  fake_l2cap()->set_connection_parameter_update_request_responder([&](auto handle, auto params) {
    l2cap_conn_param_update_count++;
    return true;
  });

  test_device()->set_le_connection_parameters_callback(
      [&](auto address, auto params) { hci_update_conn_param_count++; });

  test_device()->SetDefaultCommandStatus(hci::kLEConnectionUpdate,
                                         hci::StatusCode::kUnsupportedRemoteFeature);

  RunLoopFor(kLEConnectionPausePeripheral);
  ASSERT_TRUE(conn_handle);
  EXPECT_TRUE(conn_handle->active());
  EXPECT_EQ(0u, hci_update_conn_param_count);
  EXPECT_EQ(1u, l2cap_conn_param_update_count);

  test_device()->ClearDefaultCommandStatus(hci::kLEConnectionUpdate);

  // l2cap request should not be called on subsequent events
  test_device()->SendLEConnectionUpdateCompleteSubevent(conn_handle->handle(),
                                                        hci::LEConnectionParameters(),
                                                        hci::StatusCode::kUnsupportedRemoteFeature);

  RunLoopUntilIdle();
  EXPECT_EQ(1u, l2cap_conn_param_update_count);
}

// A peripheral should not attempt to handle the next LE Connection Update Complete event if the
// status of the LE Connection Update command is not success.
TEST_F(GAP_LowEnergyConnectionManagerTest,
       PeripheralDoesNotSendL2capConnParamReqAfterConnUpdateCommandStatusError) {
  auto peer = std::make_unique<FakePeer>(kAddress0);

  // Connection Parameter Update procedure supported by controller.
  constexpr hci::LESupportedFeatures kLEFeatures{
      static_cast<uint64_t>(hci::LESupportedFeature::kConnectionParametersRequestProcedure)};
  peer->set_le_features(kLEFeatures);
  test_device()->AddPeer(std::move(peer));

  // First create a fake incoming connection with local host as peripheral.
  test_device()->ConnectLowEnergy(kAddress0, hci::ConnectionRole::kSlave);
  RunLoopUntilIdle();

  auto link = MoveLastRemoteInitiated();
  ASSERT_TRUE(link);

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  conn_mgr()->RegisterRemoteInitiatedLink(std::move(link), BondableMode::Bondable,
                                          [&](auto result) {
                                            ASSERT_TRUE(result.is_ok());
                                            conn_handle = result.take_value();
                                          });

  size_t l2cap_conn_param_update_count = 0;
  size_t hci_update_conn_param_count = 0;

  fake_l2cap()->set_connection_parameter_update_request_responder([&](auto handle, auto params) {
    l2cap_conn_param_update_count++;
    return true;
  });

  test_device()->set_le_connection_parameters_callback(
      [&](auto address, auto params) { hci_update_conn_param_count++; });

  test_device()->SetDefaultCommandStatus(hci::kLEConnectionUpdate,
                                         hci::StatusCode::kUnspecifiedError);

  RunLoopFor(kLEConnectionPausePeripheral);
  ASSERT_TRUE(conn_handle);
  EXPECT_TRUE(conn_handle->active());
  EXPECT_EQ(0u, hci_update_conn_param_count);
  EXPECT_EQ(0u, l2cap_conn_param_update_count);

  test_device()->ClearDefaultCommandStatus(hci::kLEConnectionUpdate);

  // l2cap request should not be called on subsequent events
  test_device()->SendLEConnectionUpdateCompleteSubevent(conn_handle->handle(),
                                                        hci::LEConnectionParameters(),
                                                        hci::StatusCode::kUnsupportedRemoteFeature);

  RunLoopUntilIdle();
  EXPECT_EQ(0u, l2cap_conn_param_update_count);
}

TEST_F(GAP_LowEnergyConnectionManagerTest, HciUpdateConnParamsAfterInterrogation) {
  constexpr hci::LESupportedFeatures kLEFeatures{
      static_cast<uint64_t>(hci::LESupportedFeature::kConnectionParametersRequestProcedure)};

  auto peer = std::make_unique<FakePeer>(kAddress0);
  peer->set_le_features(kLEFeatures);
  test_device()->AddPeer(std::move(peer));

  // First create a fake incoming connection.
  test_device()->ConnectLowEnergy(kAddress0, hci::ConnectionRole::kSlave);

  RunLoopUntilIdle();

  auto link = MoveLastRemoteInitiated();
  ASSERT_TRUE(link);

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  conn_mgr()->RegisterRemoteInitiatedLink(std::move(link), BondableMode::Bondable,
                                          [&](auto result) {
                                            ASSERT_TRUE(result.is_ok());
                                            conn_handle = result.take_value();
                                          });

  size_t l2cap_conn_param_update_count = 0;
  fake_l2cap()->set_connection_parameter_update_request_responder(
      [&](auto handle, const auto params) {
        l2cap_conn_param_update_count++;
        return true;
      });

  size_t hci_update_conn_param_count = 0;
  test_device()->set_le_connection_parameters_callback(
      [&](auto address, const hci::LEConnectionParameters& params) {
        // FakeController will pick an interval between min and max interval.
        EXPECT_TRUE(params.interval() >= hci::defaults::kLEConnectionIntervalMin &&
                    params.interval() <= hci::defaults::kLEConnectionIntervalMax);
        EXPECT_EQ(0u, params.latency());
        EXPECT_EQ(hci::defaults::kLESupervisionTimeout, params.supervision_timeout());
        hci_update_conn_param_count++;
      });

  RunLoopUntilIdle();
  ASSERT_TRUE(conn_handle);
  EXPECT_TRUE(conn_handle->active());
  EXPECT_EQ(0u, l2cap_conn_param_update_count);
  EXPECT_EQ(0u, hci_update_conn_param_count);

  RunLoopFor(kLEConnectionPausePeripheral);
  EXPECT_EQ(0u, l2cap_conn_param_update_count);
  EXPECT_EQ(1u, hci_update_conn_param_count);
}

TEST_F(GAP_LowEnergyConnectionManagerTest,
       CentralUpdatesConnectionParametersToDefaultsAfterInitialization) {
  // Set up a connection.
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  ASSERT_TRUE(peer->le());

  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));

  size_t hci_update_conn_param_count = 0;
  test_device()->set_le_connection_parameters_callback(
      [&](auto address, const hci::LEConnectionParameters& params) {
        // FakeController will pick an interval between min and max interval.
        EXPECT_TRUE(params.interval() >= hci::defaults::kLEConnectionIntervalMin &&
                    params.interval() <= hci::defaults::kLEConnectionIntervalMax);
        EXPECT_EQ(0u, params.latency());
        EXPECT_EQ(hci::defaults::kLESupervisionTimeout, params.supervision_timeout());
        hci_update_conn_param_count++;
      });

  std::unique_ptr<LowEnergyConnectionHandle> conn;
  conn_mgr()->Connect(
      peer->identifier(),
      [&](auto result) {
        ASSERT_TRUE(result.is_ok());
        conn = result.take_value();
      },
      kConnectionOptions);

  RunLoopUntilIdle();
  EXPECT_EQ(0u, hci_update_conn_param_count);

  RunLoopFor(kLEConnectionPauseCentral);
  EXPECT_EQ(1u, hci_update_conn_param_count);
  EXPECT_TRUE(conn);
}

TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectCalledForPeerBeingInterrogated) {
  // Set up a connection.
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  ASSERT_TRUE(peer->le());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  // Prevent remote features event from being received.
  test_device()->SetDefaultCommandStatus(hci::kLEReadRemoteFeatures, hci::StatusCode::kSuccess);

  conn_mgr()->Connect(
      peer->identifier(), [&](auto result) { ASSERT_TRUE(result.is_error()); }, kConnectionOptions);

  RunLoopUntilIdle();
  // Interrogation should not complete.
  EXPECT_FALSE(peer->le()->features().has_value());

  // Connect to same peer again, before interrogation has completed.
  // No asserts should fail.
  conn_mgr()->Connect(
      peer->identifier(), [&](auto result) { ASSERT_TRUE(result.is_error()); }, kConnectionOptions);
  RunLoopUntilIdle();
}

LowEnergyConnectionManager::ConnectionResultCallback MakeConnectionResultCallback(
    std::unique_ptr<LowEnergyConnectionHandle>& conn_handle) {
  return [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
    EXPECT_TRUE(conn_handle);
    EXPECT_TRUE(conn_handle->active());
  };
}

// Test that active connections not meeting the requirements for Secure Connections Only mode are
// disconnected when the security mode is changed to SC Only.
TEST_F(GAP_LowEnergyConnectionManagerTest, SecureConnectionsOnlyDisconnectsInsufficientSecurity) {
  Peer* encrypted_peer = peer_cache()->NewPeer(kAddress0, true);
  Peer* unencrypted_peer = peer_cache()->NewPeer(kAddress1, true);
  Peer* secure_authenticated_peer = peer_cache()->NewPeer(kAddress3, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0));
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1));
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress3));

  std::unique_ptr<LowEnergyConnectionHandle> unencrypted_conn_handle, encrypted_conn_handle,
      secure_authenticated_conn_handle;
  EXPECT_TRUE(connected_peers().empty());
  conn_mgr()->Connect(unencrypted_peer->identifier(),
                      MakeConnectionResultCallback(unencrypted_conn_handle), kConnectionOptions);
  conn_mgr()->Connect(encrypted_peer->identifier(),
                      MakeConnectionResultCallback(encrypted_conn_handle), kConnectionOptions);
  conn_mgr()->Connect(secure_authenticated_peer->identifier(),
                      MakeConnectionResultCallback(secure_authenticated_conn_handle),
                      kConnectionOptions);
  RunLoopUntilIdle();
  std::function<void(sm::Status)> pair_cb = [](sm::Status s) { ASSERT_EQ(sm::Status(), s); };
  EXPECT_EQ(3u, connected_peers().size());
  ASSERT_TRUE(unencrypted_conn_handle);
  ASSERT_TRUE(encrypted_conn_handle);
  ASSERT_TRUE(secure_authenticated_conn_handle);
  EXPECT_TRUE(unencrypted_conn_handle->active());
  EXPECT_TRUE(secure_authenticated_conn_handle->active());
  EXPECT_TRUE(encrypted_conn_handle->active());

  // "Pair" to the encrypted peers to get to the correct security level.
  conn_mgr()->Pair(encrypted_peer->identifier(), sm::SecurityLevel::kEncrypted,
                   sm::BondableMode::Bondable, pair_cb);
  conn_mgr()->Pair(secure_authenticated_peer->identifier(), sm::SecurityLevel::kSecureAuthenticated,
                   sm::BondableMode::Bondable, pair_cb);
  RunLoopUntilIdle();
  EXPECT_EQ(sm::SecurityLevel::kNoSecurity, unencrypted_conn_handle->security().level());
  EXPECT_EQ(sm::SecurityLevel::kEncrypted, encrypted_conn_handle->security().level());
  EXPECT_EQ(sm::SecurityLevel::kSecureAuthenticated,
            secure_authenticated_conn_handle->security().level());

  // Setting Secure Connections Only mode causes connections not allowed under this mode to be
  // disconnected (in this case, `encrypted_peer` is encrypted, SC-generated, and with max
  // encryption key size, but not authenticated).
  conn_mgr()->SetSecurityMode(LeSecurityMode::SecureConnectionsOnly);
  RunLoopUntilIdle();
  EXPECT_EQ(LeSecurityMode::SecureConnectionsOnly, conn_mgr()->security_mode());
  EXPECT_EQ(2u, connected_peers().size());
  EXPECT_TRUE(unencrypted_conn_handle->active());
  EXPECT_TRUE(secure_authenticated_conn_handle->active());
  EXPECT_FALSE(encrypted_conn_handle->active());
}

// Test that both existing and new peers pick up on a change to Secure Connections Only mode.
TEST_F(GAP_LowEnergyConnectionManagerTest, SetSecureConnectionsOnlyModeWorks) {
  // LE Connection Manager defaults to Mode 1.
  EXPECT_EQ(LeSecurityMode::Mode1, conn_mgr()->security_mode());

  // This peer will already be connected when we set LE Secure Connections Only mode.
  Peer* existing_peer = peer_cache()->NewPeer(kAddress1, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1));
  std::unique_ptr<LowEnergyConnectionHandle> existing_conn_handle;
  RunLoopUntilIdle();

  conn_mgr()->Connect(existing_peer->identifier(),
                      MakeConnectionResultCallback(existing_conn_handle), kConnectionOptions);
  RunLoopUntilIdle();
  fxl::WeakPtr<TestSm> existing_peer_sm = TestSmByHandle(existing_conn_handle->handle());
  ASSERT_TRUE(existing_peer_sm);
  EXPECT_EQ(LeSecurityMode::Mode1, existing_peer_sm->security_mode());
  EXPECT_EQ(1u, connected_peers().size());

  conn_mgr()->SetSecurityMode(LeSecurityMode::SecureConnectionsOnly);
  RunLoopUntilIdle();

  EXPECT_EQ(LeSecurityMode::SecureConnectionsOnly, existing_peer_sm->security_mode());

  // This peer is connected after setting LE Secure Connections Only mode.
  Peer* new_peer = peer_cache()->NewPeer(kAddress3, true);
  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress3));
  std::unique_ptr<LowEnergyConnectionHandle> new_conn_handle;

  conn_mgr()->Connect(new_peer->identifier(), MakeConnectionResultCallback(new_conn_handle),
                      kConnectionOptions);
  RunLoopUntilIdle();
  fxl::WeakPtr<TestSm> new_peer_sm = TestSmByHandle(new_conn_handle->handle());
  ASSERT_TRUE(new_peer_sm);
  EXPECT_EQ(2u, connected_peers().size());

  EXPECT_EQ(LeSecurityMode::SecureConnectionsOnly, new_peer_sm->security_mode());
}

TEST_F(GAP_LowEnergyConnectionManagerTest,
       ConnectAndInterrogateSecondPeerDuringInterrogationOfFirstPeer) {
  auto* peer_0 = peer_cache()->NewPeer(kAddress0, true);
  ASSERT_TRUE(peer_0->le());

  auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0);
  auto fake_peer_0_ptr = fake_peer_0.get();
  test_device()->AddPeer(std::move(fake_peer_0));

  // Prevent remote features event from being received.
  test_device()->SetDefaultCommandStatus(hci::kLEReadRemoteFeatures, hci::StatusCode::kSuccess);

  std::unique_ptr<LowEnergyConnectionHandle> conn_0;
  conn_mgr()->Connect(
      peer_0->identifier(),
      [&conn_0](auto result) {
        ASSERT_TRUE(result.is_ok());
        conn_0 = result.take_value();
        ASSERT_TRUE(conn_0);
      },
      kConnectionOptions);

  RunLoopUntilIdle();
  // Interrogation should not complete.
  EXPECT_FALSE(peer_0->le()->connected());
  EXPECT_FALSE(conn_0);

  auto* peer_1 = peer_cache()->NewPeer(kAddress1, true);
  ASSERT_TRUE(peer_1->le());

  auto fake_peer_1 = std::make_unique<FakePeer>(kAddress1);
  auto fake_peer_1_ptr = fake_peer_1.get();
  test_device()->AddPeer(std::move(fake_peer_1));

  // Connect to different peer, before interrogation has completed.
  std::unique_ptr<LowEnergyConnectionHandle> conn_1;
  conn_mgr()->Connect(
      peer_1->identifier(),
      [&conn_1](auto result) {
        ASSERT_TRUE(result.is_ok());
        conn_1 = result.take_value();
        ASSERT_TRUE(conn_1);
      },
      kConnectionOptions);
  RunLoopUntilIdle();

  // Complete interrogation of peer_0
  ASSERT_FALSE(fake_peer_0_ptr->logical_links().empty());
  auto handle_0 = *fake_peer_0_ptr->logical_links().begin();
  hci::LEReadRemoteFeaturesCompleteSubeventParams response;
  response.connection_handle = htole16(handle_0);
  response.status = hci::kSuccess;
  response.le_features = 0u;
  test_device()->SendLEMetaEvent(hci::kLEReadRemoteFeaturesCompleteSubeventCode,
                                 BufferView(&response, sizeof(response)));
  RunLoopUntilIdle();
  EXPECT_TRUE(conn_0);
  EXPECT_TRUE(peer_0->le()->connected());

  // Complete interrogation of peer_1
  ASSERT_FALSE(fake_peer_1_ptr->logical_links().empty());
  auto handle_1 = *fake_peer_0_ptr->logical_links().begin();
  response.connection_handle = htole16(handle_1);
  test_device()->SendLEMetaEvent(hci::kLEReadRemoteFeaturesCompleteSubeventCode,
                                 BufferView(&response, sizeof(response)));
  RunLoopUntilIdle();
  EXPECT_TRUE(conn_1);
  EXPECT_TRUE(peer_1->le()->connected());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectSecondPeerDuringInterrogationOfFirstPeer) {
  auto* peer_0 = peer_cache()->NewPeer(kAddress0, true);
  ASSERT_TRUE(peer_0->le());

  auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0);
  auto fake_peer_0_ptr = fake_peer_0.get();
  test_device()->AddPeer(std::move(fake_peer_0));

  // Prevent remote features event from being received.
  test_device()->SetDefaultCommandStatus(hci::kLEReadRemoteFeatures, hci::StatusCode::kSuccess);

  std::unique_ptr<LowEnergyConnectionHandle> conn_0;
  conn_mgr()->Connect(
      peer_0->identifier(),
      [&](auto result) {
        ASSERT_TRUE(result.is_ok());
        conn_0 = result.take_value();
      },
      kConnectionOptions);

  RunLoopUntilIdle();
  // Interrogation should not complete.
  EXPECT_FALSE(peer_0->le()->connected());
  EXPECT_FALSE(conn_0);

  test_device()->ClearDefaultCommandStatus(hci::kLEReadRemoteFeatures);
  // Stall connection complete for peer 1.
  test_device()->SetDefaultCommandStatus(hci::kLECreateConnection, hci::StatusCode::kSuccess);

  auto* peer_1 = peer_cache()->NewPeer(kAddress1, true);
  ASSERT_TRUE(peer_1->le());

  auto fake_peer_1 = std::make_unique<FakePeer>(kAddress1);
  test_device()->AddPeer(std::move(fake_peer_1));

  // Connect to different peer, before interrogation has completed.
  conn_mgr()->Connect(
      peer_1->identifier(), [&](auto result) { EXPECT_TRUE(result.is_error()); },
      kConnectionOptions);
  RunLoopUntilIdle();

  // Complete interrogation of peer_0. No asserts should fail.
  ASSERT_FALSE(fake_peer_0_ptr->logical_links().empty());
  auto handle_0 = *fake_peer_0_ptr->logical_links().begin();
  hci::LEReadRemoteFeaturesCompleteSubeventParams response;
  response.connection_handle = htole16(handle_0);
  response.status = hci::kSuccess;
  response.le_features = 0u;
  test_device()->SendLEMetaEvent(hci::kLEReadRemoteFeaturesCompleteSubeventCode,
                                 BufferView(&response, sizeof(response)));
  RunLoopUntilIdle();
  EXPECT_TRUE(conn_0);
  EXPECT_TRUE(peer_0->le()->connected());
}

TEST_F(GAP_LowEnergyConnectionManagerTest,
       SynchonousInterrogationAndNoCallbackRetainsConnectionRef) {
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  ASSERT_TRUE(peer->le());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  std::unique_ptr<LowEnergyConnectionHandle> conn;
  conn_mgr()->Connect(
      peer->identifier(),
      [&](auto result) {
        ASSERT_TRUE(result.is_ok());
        conn = result.take_value();
      },
      kConnectionOptions);

  RunLoopUntilIdle();
  EXPECT_TRUE(peer->le()->connected());
  EXPECT_TRUE(conn);

  // Disconnect
  conn = nullptr;
  RunLoopUntilIdle();

  // Second interrogation will complete synchronously because peer has already been interrogated.
  bool conn_cb_called = false;
  conn_mgr()->Connect(
      peer->identifier(),
      [&](auto result) {
        conn_cb_called = true;
        EXPECT_TRUE(result.is_ok());
        // Don't retain ref.
      },
      kConnectionOptions);
  // Wait for connect complete event.
  RunLoopUntilIdle();
  EXPECT_TRUE(conn_cb_called);
}

TEST_F(GAP_LowEnergyConnectionManagerTest, AutoConnectSkipsScanning) {
  auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  size_t scan_cb_count = 0;
  test_device()->set_scan_state_callback([&scan_cb_count](bool enabled) { scan_cb_count++; });

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto callback = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
    EXPECT_TRUE(conn_handle->active());
  };

  EXPECT_TRUE(connected_peers().empty());
  LowEnergyConnectionOptions options{.auto_connect = true};
  conn_mgr()->Connect(peer->identifier(), callback, options);
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

  RunLoopUntilIdle();

  EXPECT_EQ(1u, connected_peers().size());
  EXPECT_EQ(1u, connected_peers().count(kAddress0));

  ASSERT_TRUE(conn_handle);
  EXPECT_TRUE(conn_handle->active());
  EXPECT_EQ(peer->identifier(), conn_handle->peer_identifier());
  EXPECT_FALSE(peer->temporary());
  EXPECT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());
  EXPECT_EQ(scan_cb_count, 0u);
}

TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectSinglePeerStartDiscoveryFailed) {
  auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  size_t connect_cb_count = 0;
  auto callback = [&connect_cb_count](auto result) {
    EXPECT_TRUE(result.is_error());
    connect_cb_count++;
  };

  // Cause discovery to fail.
  test_device()->SetDefaultCommandStatus(hci::kLESetScanEnable,
                                         hci::StatusCode::kCommandDisallowed);

  EXPECT_TRUE(connected_peers().empty());
  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

  RunLoopUntilIdle();
  EXPECT_EQ(connect_cb_count, 1u);
  EXPECT_FALSE(peer->temporary());
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectSinglePeerDiscoveryFailedDuringScan) {
  auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());

  // Don't add peer to FakeController to prevent scan from completing.

  size_t connect_cb_count = 0;
  auto callback = [&connect_cb_count](auto result) {
    EXPECT_TRUE(result.is_error());
    connect_cb_count++;
  };

  EXPECT_TRUE(connected_peers().empty());
  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
  RunLoopUntilIdle();
  EXPECT_EQ(connect_cb_count, 0u);

  // Cause discovery to fail when attempting to restart scan after scan period ends.
  test_device()->SetDefaultCommandStatus(hci::kLESetScanEnable,
                                         hci::StatusCode::kCommandDisallowed);
  RunLoopFor(kLEGeneralDiscoveryScanMin);
  EXPECT_EQ(connect_cb_count, 1u);
  EXPECT_FALSE(peer->temporary());
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, PeerDisconnectBeforeInterrogationCompletes) {
  auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  auto fake_peer_ptr = fake_peer.get();
  test_device()->AddPeer(std::move(fake_peer));

  // Cause interrogation to stall by not responding with a Read Remote Version complete event.
  test_device()->SetDefaultCommandStatus(hci::kReadRemoteVersionInfo, hci::StatusCode::kSuccess);

  int connect_count = 0;
  auto callback = [&connect_count](auto result) {
    ASSERT_TRUE(result.is_error());
    connect_count++;
  };

  EXPECT_TRUE(connected_peers().empty());
  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

  RunLoopUntilIdle();

  ASSERT_FALSE(fake_peer_ptr->logical_links().empty());
  auto handle = *fake_peer_ptr->logical_links().begin();

  test_device()->Disconnect(peer->address());

  RunLoopUntilIdle();

  // Complete interrogation so that callback gets called.
  hci::ReadRemoteVersionInfoCompleteEventParams response = {};
  response.status = hci::kSuccess;
  response.connection_handle = htole16(handle);
  test_device()->SendEvent(hci::kReadRemoteVersionInfoCompleteEventCode,
                           BufferView(&response, sizeof(response)));

  RunLoopUntilIdle();
  EXPECT_EQ(0u, connected_peers().size());
  EXPECT_EQ(1, connect_count);
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, LocalDisconnectBeforeInterrogationCompletes) {
  auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  auto fake_peer_ptr = fake_peer.get();
  test_device()->AddPeer(std::move(fake_peer));

  // Cause interrogation to stall by not responding with a Read Remote Version complete event.
  test_device()->SetDefaultCommandStatus(hci::kReadRemoteVersionInfo, hci::StatusCode::kSuccess);

  int connect_count = 0;
  auto callback = [&connect_count](auto result) {
    ASSERT_TRUE(result.is_error());
    connect_count++;
  };

  EXPECT_TRUE(connected_peers().empty());
  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

  RunLoopUntilIdle();

  ASSERT_FALSE(fake_peer_ptr->logical_links().empty());
  auto handle = *fake_peer_ptr->logical_links().begin();

  conn_mgr()->Disconnect(peer->identifier());

  RunLoopUntilIdle();

  // Complete interrogation so that callback gets called.
  hci::ReadRemoteVersionInfoCompleteEventParams response = {};
  response.status = hci::kSuccess;
  response.connection_handle = htole16(handle);
  test_device()->SendEvent(hci::kReadRemoteVersionInfoCompleteEventCode,
                           BufferView(&response, sizeof(response)));

  RunLoopUntilIdle();
  EXPECT_EQ(0u, connected_peers().size());
  EXPECT_EQ(1, connect_count);
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectionFailedToBeEstablishedRetriesTwiceAndFails) {
  auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  size_t connected_count = 0;
  test_device()->set_connection_state_callback([&](auto, auto, bool connected, bool) {
    if (connected) {
      connected_count++;
    }
  });

  int connect_cb_count = 0;
  auto callback = [&connect_cb_count](auto result) {
    ASSERT_TRUE(result.is_error());
    connect_cb_count++;
  };

  EXPECT_TRUE(connected_peers().empty());

  // Cause interrogation to fail.
  test_device()->SetDefaultCommandStatus(hci::kReadRemoteVersionInfo,
                                         hci::StatusCode::kConnectionFailedToBeEstablished);

  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

  // Exhaust retries and cause connection to fail.
  for (size_t i = 0; i < kConnectDelays.size(); i++) {
    SCOPED_TRACE(i);
    if (i != 0) {
      RunLoopFor(kConnectDelays[i] - zx::nsec(1));
      EXPECT_EQ(connected_count, i);
      RunLoopFor(zx::nsec(1));
    } else {
      RunLoopFor(kConnectDelays[i]);
    }
    EXPECT_EQ(connected_count, i + 1);
    EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

    test_device()->Disconnect(kAddress0, hci::StatusCode::kConnectionFailedToBeEstablished);
    RunLoopUntilIdle();
    EXPECT_EQ(connected_count, i + 1);
    // A connect command should be sent in connect_delays[i+1]
  }

  RunLoopUntilIdle();
  EXPECT_TRUE(connected_peers().empty());
  EXPECT_EQ(connect_cb_count, 1);
  EXPECT_FALSE(peer->temporary());
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
}

TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectionFailedToBeEstablishedRetriesAndSucceeds) {
  auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto callback = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
    EXPECT_TRUE(conn_handle->active());
  };

  EXPECT_TRUE(connected_peers().empty());

  // Cause interrogation to fail.
  test_device()->SetDefaultCommandStatus(hci::kReadRemoteVersionInfo,
                                         hci::StatusCode::kConnectionFailedToBeEstablished);

  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

  RunLoopUntilIdle();
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
  EXPECT_FALSE(conn_handle);

  // Allow the next interrogation to succeed.
  test_device()->ClearDefaultCommandStatus(hci::kReadRemoteVersionInfo);

  // Disconnect should initiate retry #2 after a pause.
  test_device()->Disconnect(kAddress0, hci::StatusCode::kConnectionFailedToBeEstablished);
  RunLoopFor(zx::sec(2));
  EXPECT_EQ(1u, connected_peers().size());
  EXPECT_EQ(1u, connected_peers().count(kAddress0));
  ASSERT_TRUE(conn_handle);
  EXPECT_TRUE(conn_handle->active());
  EXPECT_FALSE(peer->temporary());
  EXPECT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());
}

TEST_F(GAP_LowEnergyConnectionManagerTest,
       ConnectionFailedToBeEstablishedAndDisconnectDuringRetryPauseTimeout) {
  auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  int connect_cb_count = 0;
  auto callback = [&](auto result) {
    ASSERT_TRUE(result.is_error());
    EXPECT_EQ(result.error(), HostError::kCanceled);
    connect_cb_count++;
  };

  EXPECT_TRUE(connected_peers().empty());

  // Cause interrogation to fail.
  test_device()->SetDefaultCommandStatus(hci::kReadRemoteVersionInfo,
                                         hci::StatusCode::kConnectionFailedToBeEstablished);

  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

  RunLoopUntilIdle();
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
  EXPECT_EQ(connect_cb_count, 0);

  // Allow the next interrogation to succeed (even though it shouldn't happen).
  test_device()->ClearDefaultCommandStatus(hci::kReadRemoteVersionInfo);

  // Peer disconnection during interrogation should also cause retry (after a pause)
  test_device()->Disconnect(kAddress0, hci::StatusCode::kConnectionFailedToBeEstablished);
  RunLoopUntilIdle();
  // Disconnect will cancel request.
  conn_mgr()->Disconnect(peer->identifier());
  // Ensure timer is canceled.
  RunLoopRepeatedlyFor(zx::sec(1));
  EXPECT_EQ(connect_cb_count, 1);
  EXPECT_EQ(0u, connected_peers().size());
  EXPECT_FALSE(peer->temporary());
  EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
}

// Tests that receiving a peer kConnectionFailedToBeEstablished disconnect event before
// interrogation fails does not crash.
TEST_F(GAP_LowEnergyConnectionManagerTest,
       ConnectionFailedToBeEstablishedDisconnectionBeforeInterrogationFails) {
  auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  int connect_cb_count = 0;
  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto callback = [&](auto result) {
    ASSERT_TRUE(result.is_ok());
    connect_cb_count++;
    conn_handle = result.take_value();
  };

  EXPECT_TRUE(connected_peers().empty());

  // Cause interrogation to stall waiting for command complete event.
  test_device()->SetDefaultCommandStatus(hci::kReadRemoteVersionInfo, hci::StatusCode::kSuccess);

  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  ASSERT_TRUE(peer->le());
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

  RunLoopUntilIdle();
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
  EXPECT_EQ(connect_cb_count, 0);

  // Let retries succeed.
  test_device()->ClearDefaultCommandStatus(hci::kReadRemoteVersionInfo);

  // Peer disconnection during interrogation should also cause retry (after a pause).
  test_device()->Disconnect(kAddress0, hci::StatusCode::kConnectionFailedToBeEstablished);
  RunLoopUntilIdle();

  // Complete interrogation with an error that will be received after the disconnect event.
  // Event params other than status will be ignored because status is an error.
  hci::ReadRemoteVersionInfoCompleteEventParams response{.status = hci::kUnknownConnectionId};
  test_device()->SendEvent(hci::kReadRemoteVersionInfoCompleteEventCode,
                           BufferView(&response, sizeof(response)));
  RunLoopUntilIdle();
  EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
  EXPECT_EQ(connect_cb_count, 0);

  // Wait for retry.
  RunLoopFor(kConnectDelays[1]);
  EXPECT_EQ(connect_cb_count, 1);
  EXPECT_TRUE(conn_handle);
  EXPECT_EQ(1u, connected_peers().size());
  EXPECT_FALSE(peer->temporary());
  EXPECT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());
}

// Behavior verified in this test:
// 1. After a successful connection + bond to establish auto-connect for a peer, an auto-connect-
//    initiated connection attempt to that peer that fails with any of `statuses_that_disable_
//    autoconnect` disables auto-connect to that peer.
// 2. After a successful ..., NON-autoconnect-inititated connection attempts (inbound or outbound)
//    to that peer that fail with any of `statuses_that_disable_autoconnect` do NOT disable auto-
//    connect to that peer.
TEST_F(GAP_LowEnergyConnectionManagerTest, ConnectSucceedsThenAutoConnectFailsDisablesAutoConnect) {
  // If an auto-connect attempt fails with any of these status codes, we disable the auto-connect
  // behavior until the next successful connection to avoid looping.
  // clang-format off
  std::array statuses_that_disable_autoconnect = {
      hci::StatusCode::kConnectionTimeout,
      hci::StatusCode::kConnectionRejectedSecurity,
      hci::StatusCode::kConnectionAcceptTimeoutExceeded,
      hci::StatusCode::kConnectionTerminatedByLocalHost,
      hci::StatusCode::kConnectionFailedToBeEstablished
  };
  // clang-format on
  // Validate that looping with a uint8_t is safe, it makes the rest of the code simpler.
  static_assert(statuses_that_disable_autoconnect.size() < std::numeric_limits<uint8_t>::max());
  for (uint8_t i = 0; i < static_cast<uint8_t>(statuses_that_disable_autoconnect.size()); ++i) {
    SCOPED_TRACE(hci::StatusCodeToString(statuses_that_disable_autoconnect[i]));
    const DeviceAddress kAddressI(DeviceAddress::Type::kLEPublic, {i});
    auto* peer = peer_cache()->NewPeer(kAddressI, /*connectable=*/true);
    auto fake_peer = std::make_unique<FakePeer>(kAddressI);
    test_device()->AddPeer(std::move(fake_peer));

    std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
    auto success_cb = [&conn_handle](auto result) {
      ASSERT_TRUE(result.is_ok());
      conn_handle = result.take_value();
      EXPECT_TRUE(conn_handle->active());
    };

    conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
    RunLoopUntilIdle();
    // Peer needs to be bonded to set auto connect
    peer->MutLe().SetBondData(sm::PairingData{});

    EXPECT_EQ(1u, connected_peers().count(kAddressI));
    ASSERT_TRUE(conn_handle);
    EXPECT_EQ(peer->identifier(), conn_handle->peer_identifier());
    EXPECT_TRUE(peer->le()->should_auto_connect());
    EXPECT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());

    // Disconnect has to be initiated by the "remote" device - locally initiated disconnects will
    // unset auto connect behavior.
    test_device()->Disconnect(peer->address());

    RunLoopUntilIdle();

    EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
    EXPECT_TRUE(peer->le()->should_auto_connect());

    // Causes interrogation to fail, so inbound connections will fail to establish. This complexity
    // is needed because inbound connections are already HCI-connected when passed to the LECM.
    test_device()->SetDefaultCommandStatus(hci::kReadRemoteVersionInfo,
                                           statuses_that_disable_autoconnect[i]);

    ConnectionResult result;
    auto failure_cb = [&result](auto res) { result = std::move(res); };
    // Create an inbound HCI connection and try to register it with the LECM
    test_device()->ConnectLowEnergy(kAddressI);
    RunLoopUntilIdle();
    auto link = MoveLastRemoteInitiated();
    ASSERT_TRUE(link);
    result = ConnectionResult{};
    conn_mgr()->RegisterRemoteInitiatedLink(std::move(link), BondableMode::Bondable, failure_cb);
    RunLoopUntilIdle();
    // We always wait until the peer disconnects to relay connection failure when dealing with
    // the 0x3e kConnectionFailedToBeEstablished error.
    if (statuses_that_disable_autoconnect[i] == hci::StatusCode::kConnectionFailedToBeEstablished) {
      test_device()->Disconnect(kAddressI, hci::StatusCode::kConnectionFailedToBeEstablished);
      RunLoopUntilIdle();
    }
    // Remote-initiated connection attempts that fail should not disable the auto-connect flag.
    ASSERT_EQ(fit::result_state::error, result.state());
    EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
    EXPECT_TRUE(peer->le()->should_auto_connect());
    // Allow successful interrogation later in the test
    test_device()->ClearDefaultCommandStatus(hci::kReadRemoteVersionInfo);

    // Set this peer to reject all connections with statuses_that_disable_autoconnect[i]
    FakePeer* peer_ref = test_device()->FindPeer(peer->address());
    ASSERT_TRUE(peer);
    peer_ref->set_connect_response(statuses_that_disable_autoconnect[i]);

    // User-initiated connection attempts that fail should not disable the auto-connect flag.
    const LowEnergyConnectionOptions kNotAutoConnectOptions{.auto_connect = false};
    conn_mgr()->Connect(peer->identifier(), failure_cb, kNotAutoConnectOptions);
    RunLoopUntilIdle();

    ASSERT_EQ(fit::result_state::error, result.state());
    EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
    EXPECT_TRUE(peer->le()->should_auto_connect());

    // Emulate an auto-connection here, as we disable the auto-connect behavior only for
    // auto-connect-initiated attempts that fail, NOT for user-initiated or remote-initiated
    // connection attempts that fail.
    result = ConnectionResult{};
    const LowEnergyConnectionOptions kAutoConnectOptions{.auto_connect = true};
    conn_mgr()->Connect(peer->identifier(), failure_cb, kAutoConnectOptions);
    ASSERT_TRUE(peer->le());
    EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());

    RunLoopUntilIdle();

    ASSERT_EQ(fit::result_state::error, result.state());
    EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
    EXPECT_FALSE(peer->le()->should_auto_connect());
  }
}

TEST_F(GAP_LowEnergyConnectionManagerTest, Inspect) {
  inspect::Inspector inspector;
  conn_mgr()->AttachInspect(inspector.GetRoot());

  auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
  auto callback = [&conn_handle](auto result) {
    ASSERT_TRUE(result.is_ok());
    conn_handle = result.take_value();
  };
  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);

  auto requests_matcher = AllOf(
      NodeMatches(NameMatches("pending_requests")),
      ChildrenMatch(ElementsAre(NodeMatches(AllOf(
          NameMatches("pending_request_0x0"),
          PropertyList(UnorderedElementsAre(StringIs("peer_id", peer->identifier().ToString()),
                                            IntIs("callbacks", 1))))))));

  auto outbound_connector_matcher_attempt_0 = AllOf(NodeMatches(AllOf(
      NameMatches("outbound_connector"),
      PropertyList(UnorderedElementsAre(StringIs("peer_id", peer->identifier().ToString()),
                                        IntIs("connection_attempt", 0), BoolIs("is_outbound", true),
                                        StringIs("state", "StartingScanning"))))));

  auto empty_connections_matcher =
      AllOf(NodeMatches(NameMatches("connections")), ChildrenMatch(::testing::IsEmpty()));

  auto conn_mgr_property_matcher =
      PropertyList(UnorderedElementsAre(IntIs("recent_connection_failures", 0)));

  auto conn_mgr_during_connecting_matcher =
      AllOf(NodeMatches(AllOf(NameMatches(LowEnergyConnectionManager::kInspectNodeName),
                              conn_mgr_property_matcher)),
            ChildrenMatch(UnorderedElementsAre(requests_matcher, empty_connections_matcher,
                                               outbound_connector_matcher_attempt_0)));

  auto hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo());
  EXPECT_THAT(hierarchy.value(), ChildrenMatch(ElementsAre(conn_mgr_during_connecting_matcher)));

  // Finish connecting.
  RunLoopUntilIdle();

  auto empty_requests_matcher =
      AllOf(NodeMatches(NameMatches("pending_requests")), ChildrenMatch(::testing::IsEmpty()));

  auto conn_matcher = NodeMatches(
      AllOf(NameMatches("connection_0x1"),
            PropertyList(UnorderedElementsAre(StringIs("peer_id", peer->identifier().ToString()),
                                              StringIs("peer_address", peer->address().ToString()),
                                              IntIs("ref_count", 1)))));

  auto connections_matcher =
      AllOf(NodeMatches(NameMatches("connections")), ChildrenMatch(ElementsAre(conn_matcher)));

  auto conn_mgr_after_connecting_matcher =
      AllOf(NodeMatches(conn_mgr_property_matcher),
            ChildrenMatch(UnorderedElementsAre(empty_requests_matcher, connections_matcher)));

  hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo());
  EXPECT_THAT(hierarchy.value(), ChildrenMatch(ElementsAre(conn_mgr_after_connecting_matcher)));

  // LECM must be destroyed before the inspector to avoid a page fault on destruction of inspect
  // properties (they try to update the inspect VMO, which is deleted on inspector destruction).
  DeleteConnMgr();
}

TEST_F(GAP_LowEnergyConnectionManagerTest, InspectFailedConnection) {
  inspect::Inspector inspector;
  conn_mgr()->AttachInspect(inspector.GetRoot());

  auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  fake_peer->set_connect_status(hci::StatusCode::kConnectionLimitExceeded);
  test_device()->AddPeer(std::move(fake_peer));

  auto callback = [](auto result) { ASSERT_TRUE(result.is_error()); };
  conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
  RunLoopUntilIdle();

  auto conn_mgr_property_matcher =
      PropertyList(UnorderedElementsAre(IntIs("recent_connection_failures", 1)));

  auto hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo());
  EXPECT_THAT(hierarchy.value(),
              ChildrenMatch(ElementsAre(NodeMatches(conn_mgr_property_matcher))));

  RunLoopFor(LowEnergyConnectionManager::kInspectRecentConnectionFailuresExpiryDuration -
             zx::nsec(1));
  hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo());
  EXPECT_THAT(hierarchy.value(),
              ChildrenMatch(ElementsAre(NodeMatches(conn_mgr_property_matcher))));

  // Failures should revert to 0 after expiry duration.
  RunLoopFor(zx::nsec(1));
  conn_mgr_property_matcher =
      PropertyList(UnorderedElementsAre(IntIs("recent_connection_failures", 0)));
  hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo());
  EXPECT_THAT(hierarchy.value(),
              ChildrenMatch(ElementsAre(NodeMatches(conn_mgr_property_matcher))));

  // LECM must be destroyed before the inspector to avoid a page fault on destruction of inspect
  // properties (they try to update the inspect VMO, which is deleted on inspector destruction).
  DeleteConnMgr();
}

// Tests for assertions that enforce invariants.
class GAP_LowEnergyConnectionManagerDeathTest : public LowEnergyConnectionManagerTest {};

// Tests that a disconnection event that occurs after a peer gets removed is handled gracefully.
TEST_F(GAP_LowEnergyConnectionManagerDeathTest, DisconnectAfterPeerRemovalAsserts) {
  // Set up a connection.
  auto* peer = peer_cache()->NewPeer(kAddress0, true);
  EXPECT_TRUE(peer->temporary());

  auto fake_peer = std::make_unique<FakePeer>(kAddress0);
  test_device()->AddPeer(std::move(fake_peer));

  std::unique_ptr<LowEnergyConnectionHandle> conn;
  conn_mgr()->Connect(peer->identifier(), MakeConnectionResultCallback(conn), kConnectionOptions);
  RunLoopUntilIdle();
  ASSERT_TRUE(conn);

  hci::ConnectionHandle handle = conn->handle();

  EXPECT_DEATH_IF_SUPPORTED(
      {
        // Remove the peer without removing it from the cache. Normally this is not recommended as
        // implied by the name of the function but it is possible for this invariant to be broken
        // due to programmer error. The connection manager should assert this invariant.
        peer->MutLe().SetConnectionState(Peer::ConnectionState::kNotConnected);
        __UNUSED auto _ = peer_cache()->RemoveDisconnectedPeer(peer->identifier());

        test_device()->SendDisconnectionCompleteEvent(handle);
        RunLoopUntilIdle();
      },
      ".*");
}

// Test fixture for tests that disconnect a connection in various ways and expect that
// controller packet counts are not cleared on disconnecting, but are cleared on disconnection
// complete. Tests should disconnect conn_handle0().
class PendingPacketsTest : public LowEnergyConnectionManagerTest {
 public:
  PendingPacketsTest() = default;
  ~PendingPacketsTest() override = default;

  void SetUp() override {
    LowEnergyConnectionManagerTest::SetUp();
    const DeviceAddress kPeerAddr0(DeviceAddress::Type::kLEPublic, {1});
    const DeviceAddress kPeerAddr1(DeviceAddress::Type::kLEPublic, {2});

    peer0_ = peer_cache()->NewPeer(kPeerAddr0, true);
    EXPECT_TRUE(peer0_->temporary());
    test_device()->AddPeer(std::make_unique<FakePeer>(kPeerAddr0));

    peer1_ = peer_cache()->NewPeer(kPeerAddr1, true);
    EXPECT_TRUE(peer1_->temporary());
    test_device()->AddPeer(std::make_unique<FakePeer>(kPeerAddr1));

    // Connect |peer0|
    conn_handle0_.reset();
    auto callback0 = [this](auto result) {
      ASSERT_TRUE(result.is_ok());
      conn_handle0_ = result.take_value();
      EXPECT_TRUE(conn_handle0_->active());
    };
    conn_mgr()->Connect(peer0_->identifier(), callback0, kConnectionOptions);
    RunLoopUntilIdle();

    // Connect |peer1|
    conn_handle1_.reset();
    auto callback1 = [this](auto result) {
      ASSERT_TRUE(result.is_ok());
      conn_handle1_ = result.take_value();
      EXPECT_TRUE(conn_handle1_->active());
    };
    conn_mgr()->Connect(peer1_->identifier(), callback1, kConnectionOptions);
    RunLoopUntilIdle();

    packet_count_ = 0;
    test_device()->SetDataCallback([&](const auto&) { packet_count_++; }, dispatcher());
    test_device()->set_auto_completed_packets_event_enabled(false);
    test_device()->set_auto_disconnection_complete_event_enabled(false);

    // Fill controller buffer by sending |kMaxNumPackets| packets to peer0.
    for (size_t i = 0; i < kLEMaxNumPackets; i++) {
      ASSERT_TRUE(acl_data_channel()->SendPacket(
          hci::ACLDataPacket::New(conn_handle0_->handle(),
                                  hci::ACLPacketBoundaryFlag::kFirstNonFlushable,
                                  hci::ACLBroadcastFlag::kPointToPoint, 1),
          l2cap::kInvalidChannelId, hci::AclDataChannel::PacketPriority::kLow));
    }

    // Queue packet for |peer1|.
    ASSERT_TRUE(acl_data_channel()->SendPacket(
        hci::ACLDataPacket::New(conn_handle1_->handle(),
                                hci::ACLPacketBoundaryFlag::kFirstNonFlushable,
                                hci::ACLBroadcastFlag::kPointToPoint, 1),
        l2cap::kInvalidChannelId, hci::AclDataChannel::PacketPriority::kLow));

    RunLoopUntilIdle();

    // Packet for |peer1| should not have been sent because controller buffer is full.
    EXPECT_EQ(kLEMaxNumPackets, packet_count_);

    handle0_ = conn_handle0_->handle();
  }

  void TearDown() override {
    RunLoopUntilIdle();

    // Packet for |peer1| should not have been sent before Disconnection Complete event.
    EXPECT_EQ(kLEMaxNumPackets, packet_count_);

    // This makes FakeController send us the HCI Disconnection Complete event.
    test_device()->SendDisconnectionCompleteEvent(handle0_);
    RunLoopUntilIdle();

    // |peer0|'s link should have been unregistered.
    ASSERT_FALSE(acl_data_channel()->SendPacket(
        hci::ACLDataPacket::New(handle0_, hci::ACLPacketBoundaryFlag::kFirstNonFlushable,
                                hci::ACLBroadcastFlag::kPointToPoint, 1),
        l2cap::kInvalidChannelId, hci::AclDataChannel::PacketPriority::kLow));

    // Packet for |peer1| should have been sent.
    EXPECT_EQ(kLEMaxNumPackets + 1, packet_count_);

    peer0_ = nullptr;
    peer1_ = nullptr;
    conn_handle0_.reset();
    conn_handle1_.reset();

    LowEnergyConnectionManagerTest::TearDown();
  }

  Peer* peer0() { return peer0_; }
  std::unique_ptr<LowEnergyConnectionHandle>& conn_handle0() { return conn_handle0_; }

 private:
  size_t packet_count_;
  Peer* peer0_;
  Peer* peer1_;
  hci::ConnectionHandle handle0_;
  std::unique_ptr<LowEnergyConnectionHandle> conn_handle0_;
  std::unique_ptr<LowEnergyConnectionHandle> conn_handle1_;
};

using GAP_LowEnergyConnectionManagerPendingPacketsTest = PendingPacketsTest;

TEST_F(GAP_LowEnergyConnectionManagerPendingPacketsTest, Disconnect) {
  // Send HCI Disconnect to controller.
  EXPECT_TRUE(conn_mgr()->Disconnect(peer0()->identifier()));
}

TEST_F(GAP_LowEnergyConnectionManagerPendingPacketsTest, ReleaseRef) {
  // Releasing ref should send HCI Disconnect to controller.
  conn_handle0().reset();
}

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