// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/gap/pairing_state.h"

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

#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/gap/fake_pairing_delegate.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/gap/peer_cache.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/hci/fake_bredr_connection.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/sm/types.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/controller_test.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/fake_peer.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/inspect.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/inspect_util.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/mock_controller.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/test_packets.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/transport/error.h"

namespace bt::gap {
namespace {

using namespace inspect::testing;

using hci::testing::FakeBrEdrConnection;
using hci_spec::kUserConfirmationRequestEventCode;
using hci_spec::kUserPasskeyNotificationEventCode;
using hci_spec::kUserPasskeyRequestEventCode;
using pw::bluetooth::emboss::AuthenticationRequirements;
using pw::bluetooth::emboss::IoCapability;

const hci_spec::ConnectionHandle kTestHandle(0x0A0B);
const DeviceAddress kLocalAddress(DeviceAddress::Type::kBREDR,
                                  {0x22, 0x11, 0x00, 0xCC, 0xBB, 0xAA});
const DeviceAddress kPeerAddress(DeviceAddress::Type::kBREDR,
                                 {0x99, 0x88, 0x77, 0xFF, 0xEE, 0xDD});
const auto kTestLocalIoCap = sm::IOCapability::kDisplayYesNo;
const auto kTestPeerIoCap = IoCapability::DISPLAY_ONLY;
const uint32_t kTestPasskey = 123456;
const auto kTestLinkKeyValue = UInt128{0x00,
                                       0x00,
                                       0x00,
                                       0x00,
                                       0x00,
                                       0x00,
                                       0x00,
                                       0x00,
                                       0x00,
                                       0x00,
                                       0x00,
                                       0x00,
                                       0x00,
                                       0x00,
                                       0x00,
                                       0x01};
const hci_spec::LinkKey kTestLinkKey(kTestLinkKeyValue, 0, 0);
const auto kTestUnauthenticatedLinkKeyType192 =
    hci_spec::LinkKeyType::kUnauthenticatedCombination192;
const auto kTestAuthenticatedLinkKeyType192 =
    hci_spec::LinkKeyType::kAuthenticatedCombination192;
const auto kTestUnauthenticatedLinkKeyType256 =
    hci_spec::LinkKeyType::kUnauthenticatedCombination256;
const auto kTestLegacyLinkKeyType = hci_spec::LinkKeyType::kCombination;
const auto kTestChangedLinkKeyType = hci_spec::LinkKeyType::kChangedCombination;
const BrEdrSecurityRequirements kNoSecurityRequirements{
    .authentication = false, .secure_connections = false};

void NoOpStatusCallback(hci_spec::ConnectionHandle, hci::Result<>) {}
void NoOpUserConfirmationCallback(bool) {}
void NoOpUserPasskeyCallback(std::optional<uint32_t>) {}

class NoOpPairingDelegate final : public PairingDelegate {
 public:
  NoOpPairingDelegate(sm::IOCapability io_capability)
      : io_capability_(io_capability), weak_self_(this) {}

  PairingDelegate::WeakPtr GetWeakPtr() { return weak_self_.GetWeakPtr(); }

  // PairingDelegate overrides that do nothing.
  ~NoOpPairingDelegate() override = default;
  sm::IOCapability io_capability() const override { return io_capability_; }
  void CompletePairing(PeerId peer_id, sm::Result<> status) override {}
  void ConfirmPairing(PeerId peer_id, ConfirmCallback confirm) override {}
  void DisplayPasskey(PeerId peer_id,
                      uint32_t passkey,
                      DisplayMethod method,
                      ConfirmCallback confirm) override {}
  void RequestPasskey(PeerId peer_id,
                      PasskeyResponseCallback respond) override {}

 private:
  const sm::IOCapability io_capability_;
  WeakSelf<PairingDelegate> weak_self_;
};

using TestBase = testing::FakeDispatcherControllerTest<testing::MockController>;
class PairingStateTest : public TestBase {
 public:
  PairingStateTest() = default;
  virtual ~PairingStateTest() = default;

  void SetUp() override {
    TestBase::SetUp();
    InitializeACLDataChannel();

    peer_cache_ = std::make_unique<PeerCache>(dispatcher());
    peer_ = peer_cache_->NewPeer(kPeerAddress, /*connectable=*/true);

    auth_request_count_ = 0;
    send_auth_request_callback_ = [this]() { auth_request_count_++; };

    connection_ = MakeFakeConnection();
  }

  void TearDown() override {
    peer_ = nullptr;
    peer_cache_ = nullptr;

    EXPECT_CMD_PACKET_OUT(test_device(),
                          testing::DisconnectPacket(kTestHandle));
    connection_.reset();

    TestBase::TearDown();
  }

  fit::closure MakeAuthRequestCallback() {
    return send_auth_request_callback_.share();
  }

  std::unique_ptr<FakeBrEdrConnection> MakeFakeConnection() {
    return std::make_unique<FakeBrEdrConnection>(
        kTestHandle,
        kLocalAddress,
        kPeerAddress,
        pw::bluetooth::emboss::ConnectionRole::CENTRAL,
        transport()->GetWeakPtr());
  }

  FakeBrEdrConnection* connection() const { return connection_.get(); }
  PeerCache* peer_cache() const { return peer_cache_.get(); }
  Peer* peer() const { return peer_; }
  size_t auth_request_count() const { return auth_request_count_; }

 private:
  std::unique_ptr<PeerCache> peer_cache_;
  Peer* peer_;
  size_t auth_request_count_;
  fit::closure send_auth_request_callback_;
  std::unique_ptr<FakeBrEdrConnection> connection_;
};

class PairingStateDeathTest : public PairingStateTest {};

TEST_F(PairingStateTest, PairingStateStartsAsResponder) {
  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             NoOpStatusCallback);
  EXPECT_FALSE(pairing_state.initiator());
}

TEST_F(PairingStateTest, PairingStateRemainsResponderAfterPeerIoCapResponse) {
  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             NoOpStatusCallback);
  pairing_state.OnIoCapabilityResponse(kTestPeerIoCap);
  EXPECT_EQ(0u, auth_request_count());
  EXPECT_FALSE(pairing_state.initiator());
}

TEST_F(PairingStateTest,
       PairingStateBecomesInitiatorAfterLocalPairingInitiated) {
  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             NoOpStatusCallback);
  NoOpPairingDelegate pairing_delegate(kTestLocalIoCap);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());
  pairing_state.InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);
  EXPECT_EQ(1u, auth_request_count());
  EXPECT_TRUE(pairing_state.initiator());
}

TEST_F(PairingStateTest,
       PairingStateSendsAuthenticationRequestOnceForDuplicateRequest) {
  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             NoOpStatusCallback);
  NoOpPairingDelegate pairing_delegate(kTestLocalIoCap);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  pairing_state.InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);
  EXPECT_EQ(1u, auth_request_count());
  EXPECT_TRUE(pairing_state.initiator());

  pairing_state.InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);
  EXPECT_EQ(1u, auth_request_count());
  EXPECT_TRUE(pairing_state.initiator());
}

TEST_F(
    PairingStateTest,
    PairingStateRemainsResponderIfPairingInitiatedWhileResponderPairingInProgress) {
  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             NoOpStatusCallback);
  pairing_state.OnIoCapabilityResponse(kTestPeerIoCap);
  ASSERT_FALSE(pairing_state.initiator());

  pairing_state.InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);
  EXPECT_EQ(0u, auth_request_count());
  EXPECT_FALSE(pairing_state.initiator());
}

TEST_F(PairingStateTest, StatusCallbackMayDestroyPairingState) {
  std::unique_ptr<PairingState> pairing_state;
  bool cb_called = false;
  auto status_cb = [&pairing_state, &cb_called](
                       hci_spec::ConnectionHandle handle,
                       hci::Result<> status) {
    EXPECT_TRUE(status.is_error());
    cb_called = true;

    // Note that this lambda is owned by the PairingState so its captures are
    // invalid after this.
    pairing_state = nullptr;
  };

  pairing_state = std::make_unique<PairingState>(peer()->GetWeakPtr(),
                                                 connection(),
                                                 /*link_initiated=*/false,
                                                 MakeAuthRequestCallback(),
                                                 status_cb);

  // Unexpected event that should cause the status callback to be called with an
  // error.
  pairing_state->OnUserPasskeyNotification(kTestPasskey);

  EXPECT_TRUE(cb_called);
}

TEST_F(PairingStateTest, InitiatorCallbackMayDestroyPairingState) {
  std::unique_ptr<PairingState> pairing_state =
      std::make_unique<PairingState>(peer()->GetWeakPtr(),
                                     connection(),
                                     /*link_initiated=*/false,
                                     MakeAuthRequestCallback(),
                                     NoOpStatusCallback);
  bool cb_called = false;
  auto status_cb = [&pairing_state, &cb_called](
                       hci_spec::ConnectionHandle handle,
                       hci::Result<> status) {
    EXPECT_TRUE(status.is_error());
    cb_called = true;

    // Note that this lambda is owned by the PairingState so its captures are
    // invalid after this.
    pairing_state = nullptr;
  };
  NoOpPairingDelegate pairing_delegate(kTestLocalIoCap);
  pairing_state->SetPairingDelegate(pairing_delegate.GetWeakPtr());
  pairing_state->InitiatePairing(kNoSecurityRequirements, status_cb);

  // Unexpected event that should cause the status callback to be called with an
  // error.
  pairing_state->OnUserPasskeyNotification(kTestPasskey);

  EXPECT_TRUE(cb_called);
}

// Test helper to inspect StatusCallback invocations.
class TestStatusHandler final {
 public:
  auto MakeStatusCallback() {
    return [this](hci_spec::ConnectionHandle handle, hci::Result<> status) {
      call_count_++;
      handle_ = handle;
      status_ = status;
    };
  }

  auto call_count() const { return call_count_; }

  // Returns std::nullopt if |call_count() < 1|, otherwise values from the most
  // recent callback invocation.
  auto& handle() const { return handle_; }
  auto& status() const { return status_; }

 private:
  int call_count_ = 0;
  std::optional<hci_spec::ConnectionHandle> handle_;
  std::optional<hci::Result<>> status_;
};

TEST_F(PairingStateTest, TestStatusHandlerTracksStatusCallbackInvocations) {
  TestStatusHandler handler;
  EXPECT_EQ(0, handler.call_count());
  EXPECT_FALSE(handler.status());

  PairingState::StatusCallback status_cb = handler.MakeStatusCallback();
  EXPECT_EQ(0, handler.call_count());
  EXPECT_FALSE(handler.status());

  status_cb(hci_spec::ConnectionHandle(0x0A0B),
            ToResult(pw::bluetooth::emboss::StatusCode::PAIRING_NOT_ALLOWED));
  EXPECT_EQ(1, handler.call_count());
  ASSERT_TRUE(handler.handle());
  EXPECT_EQ(hci_spec::ConnectionHandle(0x0A0B), *handler.handle());
  ASSERT_TRUE(handler.status());
  EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::PAIRING_NOT_ALLOWED),
            *handler.status());
}

TEST_F(PairingStateTest,
       InitiatingPairingAfterErrorTriggersStatusCallbackWithError) {
  TestStatusHandler link_status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             link_status_handler.MakeStatusCallback());

  // Unexpected event that should cause the status callback to be called with an
  // error.
  pairing_state.OnUserPasskeyNotification(kTestPasskey);

  EXPECT_EQ(1, link_status_handler.call_count());
  ASSERT_TRUE(link_status_handler.handle());
  EXPECT_EQ(kTestHandle, *link_status_handler.handle());
  ASSERT_TRUE(link_status_handler.status());
  EXPECT_EQ(ToResult(HostError::kNotSupported), *link_status_handler.status());

  // Try to initiate pairing again.
  TestStatusHandler pairing_status_handler;
  pairing_state.InitiatePairing(kNoSecurityRequirements,
                                pairing_status_handler.MakeStatusCallback());

  // The status callback for pairing attempts made after a pairing failure
  // should be rejected as canceled.
  EXPECT_EQ(1, pairing_status_handler.call_count());
  ASSERT_TRUE(pairing_status_handler.handle());
  EXPECT_EQ(kTestHandle, *pairing_status_handler.handle());
  ASSERT_TRUE(pairing_status_handler.status());
  EXPECT_EQ(ToResult(HostError::kCanceled), *pairing_status_handler.status());
}

TEST_F(PairingStateTest,
       UnexpectedEncryptionChangeDoesNotTriggerStatusCallback) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(kTestLocalIoCap);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state.InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);
  static_cast<void>(pairing_state.OnLinkKeyRequest());
  static_cast<void>(pairing_state.OnIoCapabilityRequest());
  pairing_state.OnIoCapabilityResponse(kTestPeerIoCap);

  ASSERT_EQ(0, connection()->start_encryption_count());
  ASSERT_EQ(0, status_handler.call_count());

  connection()->TriggerEncryptionChangeCallback(fit::ok(true));
  EXPECT_EQ(0, status_handler.call_count());
}

TEST_F(PairingStateTest, PeerMayNotChangeLinkKeyWhenNotEncrypted) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  ASSERT_FALSE(connection()->ltk().has_value());

  pairing_state.OnLinkKeyNotification(kTestLinkKeyValue,
                                      kTestChangedLinkKeyType);

  EXPECT_FALSE(connection()->ltk().has_value());
  EXPECT_EQ(1, status_handler.call_count());
  ASSERT_TRUE(status_handler.handle());
  EXPECT_EQ(kTestHandle, *status_handler.handle());
  ASSERT_TRUE(status_handler.status());
  EXPECT_EQ(ToResult(HostError::kInsufficientSecurity),
            *status_handler.status());
}

TEST_F(PairingStateTest, PeerMayChangeLinkKeyWhenInIdleState) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  connection()->set_link_key(hci_spec::LinkKey(UInt128(), 0, 0),
                             kTestAuthenticatedLinkKeyType192);

  pairing_state.OnLinkKeyNotification(kTestLinkKeyValue,
                                      kTestChangedLinkKeyType);

  ASSERT_TRUE(connection()->ltk().has_value());
  EXPECT_EQ(kTestLinkKeyValue, connection()->ltk().value().value());
  ASSERT_TRUE(connection()->ltk_type().has_value());
  EXPECT_EQ(kTestChangedLinkKeyType, connection()->ltk_type().value());
  EXPECT_EQ(0, status_handler.call_count());
}

// Inject events that occur during the course of a successful pairing as an
// initiator, but not including enabling link encryption.
void AdvanceToEncryptionAsInitiator(PairingState* pairing_state) {
  static_cast<void>(pairing_state->OnLinkKeyRequest());
  static_cast<void>(pairing_state->OnIoCapabilityRequest());
  pairing_state->OnIoCapabilityResponse(kTestPeerIoCap);
  pairing_state->OnUserConfirmationRequest(kTestPasskey,
                                           NoOpUserConfirmationCallback);
  pairing_state->OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  pairing_state->OnLinkKeyNotification(kTestLinkKeyValue,
                                       kTestUnauthenticatedLinkKeyType192);
  pairing_state->OnAuthenticationComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);
}

TEST_F(PairingStateTest, SuccessfulEncryptionChangeTriggersStatusCallback) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(kTestLocalIoCap);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state.InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);
  AdvanceToEncryptionAsInitiator(&pairing_state);

  ASSERT_EQ(0, status_handler.call_count());

  EXPECT_EQ(1, connection()->start_encryption_count());
  connection()->TriggerEncryptionChangeCallback(fit::ok(true));
  EXPECT_EQ(1, status_handler.call_count());
  ASSERT_TRUE(status_handler.handle());
  EXPECT_EQ(kTestHandle, *status_handler.handle());
  ASSERT_TRUE(status_handler.status());
  EXPECT_EQ(fit::ok(), *status_handler.status());
}

TEST_F(PairingStateTest, EncryptionChangeErrorTriggersStatusCallbackWithError) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(kTestLocalIoCap);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  static_cast<void>(pairing_state.InitiatePairing(kNoSecurityRequirements,
                                                  NoOpStatusCallback));
  AdvanceToEncryptionAsInitiator(&pairing_state);

  ASSERT_EQ(0, status_handler.call_count());

  EXPECT_EQ(1, connection()->start_encryption_count());
  connection()->TriggerEncryptionChangeCallback(
      fit::error(Error(HostError::kInsufficientSecurity)));
  EXPECT_EQ(1, status_handler.call_count());
  ASSERT_TRUE(status_handler.handle());
  EXPECT_EQ(kTestHandle, *status_handler.handle());
  ASSERT_TRUE(status_handler.status());
  EXPECT_EQ(ToResult(HostError::kInsufficientSecurity),
            *status_handler.status());
}

TEST_F(PairingStateTest,
       EncryptionChangeToDisabledTriggersStatusCallbackWithError) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(kTestLocalIoCap);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state.InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);
  AdvanceToEncryptionAsInitiator(&pairing_state);

  ASSERT_EQ(0, status_handler.call_count());

  EXPECT_EQ(1, connection()->start_encryption_count());
  connection()->TriggerEncryptionChangeCallback(fit::ok(false));
  EXPECT_EQ(1, status_handler.call_count());
  ASSERT_TRUE(status_handler.handle());
  EXPECT_EQ(kTestHandle, *status_handler.handle());
  ASSERT_TRUE(status_handler.status());
  EXPECT_EQ(ToResult(HostError::kFailed), *status_handler.status());
}

TEST_F(PairingStateTest, EncryptionChangeToEnableCallsInitiatorCallbacks) {
  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             NoOpStatusCallback);
  NoOpPairingDelegate pairing_delegate(kTestLocalIoCap);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  TestStatusHandler status_handler_0;
  pairing_state.InitiatePairing(kNoSecurityRequirements,
                                status_handler_0.MakeStatusCallback());
  AdvanceToEncryptionAsInitiator(&pairing_state);
  EXPECT_TRUE(pairing_state.initiator());

  // Try to initiate pairing while pairing is in progress.
  TestStatusHandler status_handler_1;
  static_cast<void>(pairing_state.InitiatePairing(
      kNoSecurityRequirements, status_handler_1.MakeStatusCallback()));

  EXPECT_TRUE(pairing_state.initiator());
  ASSERT_EQ(0, status_handler_0.call_count());
  ASSERT_EQ(0, status_handler_1.call_count());

  connection()->TriggerEncryptionChangeCallback(fit::ok(true));
  EXPECT_EQ(1, status_handler_0.call_count());
  EXPECT_EQ(1, status_handler_1.call_count());
  ASSERT_TRUE(status_handler_0.handle());
  EXPECT_EQ(kTestHandle, *status_handler_0.handle());
  ASSERT_TRUE(status_handler_0.status());
  EXPECT_EQ(fit::ok(), *status_handler_0.status());
  ASSERT_TRUE(status_handler_1.handle());
  EXPECT_EQ(kTestHandle, *status_handler_1.handle());
  ASSERT_TRUE(status_handler_1.status());
  EXPECT_EQ(fit::ok(), *status_handler_1.status());

  // Errors for a new pairing shouldn't invoke the initiators' callbacks.
  pairing_state.OnUserPasskeyNotification(kTestPasskey);
  EXPECT_EQ(1, status_handler_0.call_count());
  EXPECT_EQ(1, status_handler_1.call_count());
}

TEST_F(PairingStateTest, InitiatingPairingOnResponderWaitsForPairingToFinish) {
  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             NoOpStatusCallback);
  NoOpPairingDelegate pairing_delegate(kTestLocalIoCap);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine as pairing responder.
  pairing_state.OnIoCapabilityResponse(kTestPeerIoCap);
  ASSERT_FALSE(pairing_state.initiator());
  static_cast<void>(pairing_state.OnIoCapabilityRequest());
  pairing_state.OnUserConfirmationRequest(kTestPasskey,
                                          NoOpUserConfirmationCallback);

  // Try to initiate pairing while pairing is in progress.
  TestStatusHandler status_handler;
  pairing_state.InitiatePairing(kNoSecurityRequirements,
                                status_handler.MakeStatusCallback());
  EXPECT_FALSE(pairing_state.initiator());

  // Keep advancing state machine.
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  pairing_state.OnLinkKeyNotification(kTestLinkKeyValue,
                                      kTestUnauthenticatedLinkKeyType192);

  EXPECT_FALSE(pairing_state.initiator());
  ASSERT_EQ(0, status_handler.call_count());

  // The attempt to initiate pairing should have its status callback notified.
  connection()->TriggerEncryptionChangeCallback(fit::ok(true));
  EXPECT_EQ(1, status_handler.call_count());
  ASSERT_TRUE(status_handler.handle());
  EXPECT_EQ(kTestHandle, *status_handler.handle());
  ASSERT_TRUE(status_handler.status());
  EXPECT_EQ(fit::ok(), *status_handler.status());

  // Errors for a new pairing shouldn't invoke the attempted initiator's
  // callback.
  pairing_state.OnUserPasskeyNotification(kTestPasskey);
  EXPECT_EQ(1, status_handler.call_count());
}

TEST_F(PairingStateTest, UnresolvedPairingCallbackIsCalledOnDestruction) {
  TestStatusHandler overall_status, request_status;
  {
    PairingState pairing_state(peer()->GetWeakPtr(),
                               connection(),
                               /*link_initiated=*/false,
                               MakeAuthRequestCallback(),
                               overall_status.MakeStatusCallback());
    NoOpPairingDelegate pairing_delegate(kTestLocalIoCap);
    pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

    // Advance state machine as pairing responder.
    pairing_state.OnIoCapabilityResponse(kTestPeerIoCap);
    ASSERT_FALSE(pairing_state.initiator());
    static_cast<void>(pairing_state.OnIoCapabilityRequest());
    pairing_state.OnUserConfirmationRequest(kTestPasskey,
                                            NoOpUserConfirmationCallback);

    // Try to initiate pairing while pairing is in progress.
    pairing_state.InitiatePairing(kNoSecurityRequirements,
                                  request_status.MakeStatusCallback());
    EXPECT_FALSE(pairing_state.initiator());

    // Keep advancing state machine.
    pairing_state.OnSimplePairingComplete(
        pw::bluetooth::emboss::StatusCode::SUCCESS);
    pairing_state.OnLinkKeyNotification(kTestLinkKeyValue,
                                        kTestUnauthenticatedLinkKeyType192);

    // as pairing_state falls out of scope, we expect additional pairing
    // callbacks to be called
    ASSERT_EQ(0, overall_status.call_count());
    ASSERT_EQ(0, request_status.call_count());
  }

  ASSERT_EQ(0, overall_status.call_count());

  ASSERT_EQ(1, request_status.call_count());
  ASSERT_TRUE(request_status.handle());
  EXPECT_EQ(kTestHandle, *request_status.handle());
  EXPECT_EQ(ToResult(HostError::kLinkDisconnected), *request_status.status());
}

TEST_F(PairingStateTest,
       InitiatorPairingStateRejectsIoCapReqWithoutPairingDelegate) {
  TestStatusHandler owner_status_handler;
  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             owner_status_handler.MakeStatusCallback());

  TestStatusHandler initiator_status_handler;
  // Advance state machine to Initiator Waiting IOCap Request
  pairing_state.InitiatePairing(kNoSecurityRequirements,
                                initiator_status_handler.MakeStatusCallback());
  EXPECT_TRUE(pairing_state.initiator());
  // We should permit the pairing state machine to continue even without a
  // PairingDelegate, as we may have an existing bond to restore, which can be
  // done without a PairingDelegate.
  EXPECT_EQ(0, owner_status_handler.call_count());
  EXPECT_EQ(0, initiator_status_handler.call_count());
  // We will only start the pairing process if there is no stored bond
  EXPECT_EQ(std::nullopt, pairing_state.OnLinkKeyRequest());
  // We expect to be notified that there are no IOCapabilities, as there is no
  // PairingDelegate to provide them
  EXPECT_EQ(std::nullopt, pairing_state.OnIoCapabilityRequest());
  // All callbacks should be notified of pairing failure
  EXPECT_EQ(1, owner_status_handler.call_count());
  EXPECT_EQ(1, initiator_status_handler.call_count());
  ASSERT_TRUE(initiator_status_handler.status());
  EXPECT_EQ(ToResult(HostError::kNotReady), *initiator_status_handler.status());
  EXPECT_EQ(initiator_status_handler.status(), owner_status_handler.status());
}

TEST_F(PairingStateTest,
       ResponderPairingStateRejectsIoCapReqWithoutPairingDelegate) {
  TestStatusHandler status_handler;
  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());

  // Advance state machine to Responder Waiting IOCap Request
  pairing_state.OnIoCapabilityResponse(
      pw::bluetooth::emboss::IoCapability::DISPLAY_YES_NO);
  EXPECT_FALSE(pairing_state.initiator());
  EXPECT_EQ(0, status_handler.call_count());

  // We expect to be notified that there are no IOCapabilities, as there is no
  // PairingDelegate to provide them.
  EXPECT_EQ(std::nullopt, pairing_state.OnIoCapabilityRequest());
  // All callbacks should be notified of pairing failure
  EXPECT_EQ(1, status_handler.call_count());
  ASSERT_TRUE(status_handler.status());
  EXPECT_EQ(ToResult(HostError::kNotReady), *status_handler.status());
}

TEST_F(PairingStateTest, UnexpectedLinkKeyAuthenticationRaisesError) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kDisplayOnly);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state.OnIoCapabilityResponse(IoCapability::DISPLAY_YES_NO);
  ASSERT_FALSE(pairing_state.initiator());
  static_cast<void>(pairing_state.OnIoCapabilityRequest());
  pairing_state.OnUserConfirmationRequest(kTestPasskey,
                                          NoOpUserConfirmationCallback);
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);

  // Provide an authenticated link key when this should have resulted in an
  // unauthenticated link key
  pairing_state.OnLinkKeyNotification(kTestLinkKeyValue,
                                      kTestAuthenticatedLinkKeyType192);

  EXPECT_EQ(1, status_handler.call_count());
  ASSERT_TRUE(status_handler.handle());
  EXPECT_EQ(kTestHandle, *status_handler.handle());
  ASSERT_TRUE(status_handler.status());
  EXPECT_EQ(ToResult(HostError::kInsufficientSecurity),
            *status_handler.status());
}

TEST_F(PairingStateTest, LegacyPairingLinkKeyRaisesError) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state.OnIoCapabilityResponse(IoCapability::DISPLAY_YES_NO);
  ASSERT_FALSE(pairing_state.initiator());
  static_cast<void>(pairing_state.OnIoCapabilityRequest());
  pairing_state.OnUserConfirmationRequest(kTestPasskey,
                                          NoOpUserConfirmationCallback);
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);

  // Provide a legacy pairing link key type.
  pairing_state.OnLinkKeyNotification(kTestLinkKeyValue,
                                      kTestLegacyLinkKeyType);

  EXPECT_EQ(1, status_handler.call_count());
  ASSERT_TRUE(status_handler.handle());
  EXPECT_EQ(kTestHandle, *status_handler.handle());
  ASSERT_TRUE(status_handler.status());
  EXPECT_EQ(ToResult(HostError::kInsufficientSecurity),
            *status_handler.status());
}

TEST_F(PairingStateTest, PairingSetsConnectionLinkKey) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state.OnIoCapabilityResponse(IoCapability::DISPLAY_YES_NO);
  ASSERT_FALSE(pairing_state.initiator());
  static_cast<void>(pairing_state.OnIoCapabilityRequest());
  pairing_state.OnUserConfirmationRequest(kTestPasskey,
                                          NoOpUserConfirmationCallback);
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);

  ASSERT_FALSE(connection()->ltk());
  pairing_state.OnLinkKeyNotification(kTestLinkKeyValue,
                                      kTestUnauthenticatedLinkKeyType192);
  ASSERT_TRUE(connection()->ltk());
  EXPECT_EQ(kTestLinkKeyValue, connection()->ltk()->value());

  EXPECT_EQ(0, status_handler.call_count());
}

TEST_F(PairingStateTest,
       SecureConnectionsRequiresSecureConnectionsLinkKeySuccess) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kDisplayOnly);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Set peer lmp_features: Secure Connections (Host Support)
  peer()->SetFeaturePage(
      1u,
      static_cast<uint64_t>(
          hci_spec::LMPFeature::kSecureConnectionsHostSupport));

  // Set peer lmp_features: Secure Connections (Controller Support)
  peer()->SetFeaturePage(
      2u,
      static_cast<uint64_t>(
          hci_spec::LMPFeature::kSecureConnectionsControllerSupport));

  // Advance state machine.
  pairing_state.OnIoCapabilityResponse(IoCapability::DISPLAY_YES_NO);
  ASSERT_FALSE(pairing_state.initiator());
  static_cast<void>(pairing_state.OnIoCapabilityRequest());
  pairing_state.OnUserConfirmationRequest(kTestPasskey,
                                          NoOpUserConfirmationCallback);
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);

  // Ensure that P-256 authenticated link key was provided
  pairing_state.OnLinkKeyNotification(
      kTestLinkKeyValue,
      kTestUnauthenticatedLinkKeyType256,
      /*local_secure_connections_supported=*/true);

  ASSERT_TRUE(connection()->ltk());
  EXPECT_EQ(kTestLinkKeyValue, connection()->ltk()->value());

  EXPECT_EQ(0, status_handler.call_count());
}

TEST_F(PairingStateTest,
       SecureConnectionsRequiresSecureConnectionsLinkKeyFail) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kDisplayOnly);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Set peer lmp_features: Secure Connections (Host Support)
  peer()->SetFeaturePage(
      1u,
      static_cast<uint64_t>(
          hci_spec::LMPFeature::kSecureConnectionsHostSupport));

  // Set peer lmp_features: Secure Connections (Controller Support)
  peer()->SetFeaturePage(
      2u,
      static_cast<uint64_t>(
          hci_spec::LMPFeature::kSecureConnectionsControllerSupport));

  // Advance state machine.
  pairing_state.OnIoCapabilityResponse(IoCapability::DISPLAY_YES_NO);
  ASSERT_FALSE(pairing_state.initiator());
  static_cast<void>(pairing_state.OnIoCapabilityRequest());
  pairing_state.OnUserConfirmationRequest(kTestPasskey,
                                          NoOpUserConfirmationCallback);
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);

  // Provide P-192 authenticated link key when this should have resulted in an
  // P-256 link key
  pairing_state.OnLinkKeyNotification(
      kTestLinkKeyValue,
      kTestUnauthenticatedLinkKeyType192,
      /*local_secure_connections_supported=*/true);

  EXPECT_EQ(1, status_handler.call_count());
  ASSERT_TRUE(status_handler.handle());
  EXPECT_EQ(kTestHandle, *status_handler.handle());
  ASSERT_TRUE(status_handler.status());
  EXPECT_EQ(ToResult(HostError::kInsufficientSecurity),
            *status_handler.status());
}

TEST_F(PairingStateTest,
       NumericComparisonPairingComparesPasskeyOnInitiatorDisplayYesNoSide) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  FakePairingDelegate pairing_delegate(sm::IOCapability::kDisplayYesNo);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state.InitiatePairing(kNoSecurityRequirements,
                                status_handler.MakeStatusCallback());
  ASSERT_TRUE(pairing_state.initiator());
  static_cast<void>(pairing_state.OnLinkKeyRequest());
  EXPECT_EQ(IoCapability::DISPLAY_YES_NO,
            *pairing_state.OnIoCapabilityRequest());

  pairing_state.OnIoCapabilityResponse(IoCapability::DISPLAY_YES_NO);

  pairing_delegate.SetDisplayPasskeyCallback(
      [this](PeerId peer_id,
             uint32_t value,
             PairingDelegate::DisplayMethod method,
             auto cb) {
        EXPECT_EQ(peer()->identifier(), peer_id);
        EXPECT_EQ(kTestPasskey, value);
        EXPECT_EQ(PairingDelegate::DisplayMethod::kComparison, method);
        ASSERT_TRUE(cb);
        cb(true);
      });
  bool confirmed = false;
  pairing_state.OnUserConfirmationRequest(
      kTestPasskey, [&confirmed](bool confirm) { confirmed = confirm; });
  EXPECT_TRUE(confirmed);

  pairing_delegate.SetCompletePairingCallback(
      [this](PeerId peer_id, sm::Result<> status) {
        EXPECT_EQ(peer()->identifier(), peer_id);
        EXPECT_EQ(fit::ok(), status);
      });
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);

  EXPECT_EQ(0, status_handler.call_count());
}

TEST_F(PairingStateTest,
       NumericComparisonPairingComparesPasskeyOnResponderDisplayYesNoSide) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  FakePairingDelegate pairing_delegate(sm::IOCapability::kDisplayYesNo);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state.OnIoCapabilityResponse(IoCapability::DISPLAY_YES_NO);
  ASSERT_FALSE(pairing_state.initiator());
  EXPECT_EQ(IoCapability::DISPLAY_YES_NO,
            *pairing_state.OnIoCapabilityRequest());

  pairing_delegate.SetDisplayPasskeyCallback(
      [this](PeerId peer_id,
             uint32_t value,
             PairingDelegate::DisplayMethod method,
             auto cb) {
        EXPECT_EQ(peer()->identifier(), peer_id);
        EXPECT_EQ(kTestPasskey, value);
        EXPECT_EQ(PairingDelegate::DisplayMethod::kComparison, method);
        ASSERT_TRUE(cb);
        cb(true);
      });
  bool confirmed = false;
  pairing_state.OnUserConfirmationRequest(
      kTestPasskey, [&confirmed](bool confirm) { confirmed = confirm; });
  EXPECT_TRUE(confirmed);

  pairing_delegate.SetCompletePairingCallback(
      [this](PeerId peer_id, sm::Result<> status) {
        EXPECT_EQ(peer()->identifier(), peer_id);
        EXPECT_EQ(fit::ok(), status);
      });
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);

  EXPECT_EQ(0, status_handler.call_count());
}

// v5.0, Vol 3, Part C, Sec 5.2.2.6 call this "Numeric Comparison with automatic
// confirmation on device B only and Yes/No confirmation on whether to pair on
// device A. Device A does not show the confirmation value." and it should
// result in user consent.
TEST_F(PairingStateTest,
       NumericComparisonWithoutValueRequestsConsentFromDisplayYesNoSide) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  FakePairingDelegate pairing_delegate(sm::IOCapability::kDisplayYesNo);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state.OnIoCapabilityResponse(IoCapability::NO_INPUT_NO_OUTPUT);
  ASSERT_FALSE(pairing_state.initiator());
  EXPECT_EQ(IoCapability::DISPLAY_YES_NO,
            *pairing_state.OnIoCapabilityRequest());

  pairing_delegate.SetConfirmPairingCallback([this](PeerId peer_id, auto cb) {
    EXPECT_EQ(peer()->identifier(), peer_id);
    ASSERT_TRUE(cb);
    cb(true);
  });
  bool confirmed = false;
  pairing_state.OnUserConfirmationRequest(
      kTestPasskey, [&confirmed](bool confirm) { confirmed = confirm; });
  EXPECT_TRUE(confirmed);

  pairing_delegate.SetCompletePairingCallback(
      [this](PeerId peer_id, sm::Result<> status) {
        EXPECT_EQ(peer()->identifier(), peer_id);
        EXPECT_EQ(fit::ok(), status);
      });
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);

  EXPECT_EQ(0, status_handler.call_count());
}

TEST_F(PairingStateTest, PasskeyEntryPairingDisplaysPasskeyToDisplayOnlySide) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  FakePairingDelegate pairing_delegate(sm::IOCapability::kDisplayOnly);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state.OnIoCapabilityResponse(IoCapability::KEYBOARD_ONLY);
  ASSERT_FALSE(pairing_state.initiator());
  EXPECT_EQ(IoCapability::DISPLAY_ONLY, *pairing_state.OnIoCapabilityRequest());

  pairing_delegate.SetDisplayPasskeyCallback(
      [this](PeerId peer_id,
             uint32_t value,
             PairingDelegate::DisplayMethod method,
             auto cb) {
        EXPECT_EQ(peer()->identifier(), peer_id);
        EXPECT_EQ(kTestPasskey, value);
        EXPECT_EQ(PairingDelegate::DisplayMethod::kPeerEntry, method);
        EXPECT_TRUE(cb);
      });
  pairing_state.OnUserPasskeyNotification(kTestPasskey);

  pairing_delegate.SetCompletePairingCallback(
      [this](PeerId peer_id, sm::Result<> status) {
        EXPECT_EQ(peer()->identifier(), peer_id);
        EXPECT_EQ(fit::ok(), status);
      });
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);

  EXPECT_EQ(0, status_handler.call_count());
}

TEST_F(PairingStateTest,
       PasskeyEntryPairingRequestsPasskeyFromKeyboardOnlySide) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  FakePairingDelegate pairing_delegate(sm::IOCapability::kKeyboardOnly);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state.OnIoCapabilityResponse(IoCapability::DISPLAY_ONLY);
  ASSERT_FALSE(pairing_state.initiator());
  EXPECT_EQ(IoCapability::KEYBOARD_ONLY,
            *pairing_state.OnIoCapabilityRequest());

  pairing_delegate.SetRequestPasskeyCallback([this](PeerId peer_id, auto cb) {
    EXPECT_EQ(peer()->identifier(), peer_id);
    ASSERT_TRUE(cb);
    cb(kTestPasskey);
  });
  bool cb_called = false;
  std::optional<uint32_t> passkey;
  auto passkey_cb = [&cb_called,
                     &passkey](std::optional<uint32_t> pairing_state_passkey) {
    cb_called = true;
    passkey = pairing_state_passkey;
  };

  pairing_state.OnUserPasskeyRequest(std::move(passkey_cb));
  EXPECT_TRUE(cb_called);
  ASSERT_TRUE(passkey);
  EXPECT_EQ(kTestPasskey, *passkey);

  pairing_delegate.SetCompletePairingCallback(
      [this](PeerId peer_id, sm::Result<> status) {
        EXPECT_EQ(peer()->identifier(), peer_id);
        EXPECT_EQ(fit::ok(), status);
      });
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);

  EXPECT_EQ(0, status_handler.call_count());
}

TEST_F(PairingStateTest,
       JustWorksPairingOutgoingConnectDoesNotRequestUserActionInitiator) {
  TestStatusHandler owner_status_handler;
  TestStatusHandler initiator_status_handler;
  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/true,
                             MakeAuthRequestCallback(),
                             owner_status_handler.MakeStatusCallback());

  FakePairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine to Initiator Waiting IOCap Request
  pairing_state.InitiatePairing(kNoSecurityRequirements,
                                initiator_status_handler.MakeStatusCallback());
  EXPECT_TRUE(pairing_state.initiator());
  static_cast<void>(pairing_state.OnLinkKeyRequest());
  EXPECT_EQ(IoCapability::NO_INPUT_NO_OUTPUT,
            *pairing_state.OnIoCapabilityRequest());

  pairing_state.OnIoCapabilityResponse(IoCapability::NO_INPUT_NO_OUTPUT);
  bool confirmed = false;
  pairing_state.OnUserConfirmationRequest(
      kTestPasskey, [&confirmed](bool confirm) { confirmed = confirm; });
  EXPECT_TRUE(confirmed);

  pairing_delegate.SetCompletePairingCallback(
      [this](PeerId peer_id, sm::Result<> status) {
        EXPECT_EQ(peer()->identifier(), peer_id);
        EXPECT_EQ(fit::ok(), status);
      });
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);

  EXPECT_EQ(0, owner_status_handler.call_count());
  EXPECT_EQ(0, initiator_status_handler.call_count());
}

TEST_F(PairingStateTest,
       JustWorksPairingOutgoingConnectDoesNotRequestUserActionResponder) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/true,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  FakePairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state.OnIoCapabilityResponse(IoCapability::NO_INPUT_NO_OUTPUT);
  ASSERT_FALSE(pairing_state.initiator());
  EXPECT_EQ(IoCapability::NO_INPUT_NO_OUTPUT,
            *pairing_state.OnIoCapabilityRequest());

  bool confirmed = false;
  pairing_state.OnUserConfirmationRequest(
      kTestPasskey, [&confirmed](bool confirm) { confirmed = confirm; });
  EXPECT_TRUE(confirmed);

  pairing_delegate.SetCompletePairingCallback(
      [this](PeerId peer_id, sm::Result<> status) {
        EXPECT_EQ(peer()->identifier(), peer_id);
        EXPECT_EQ(fit::ok(), status);
      });
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);

  EXPECT_EQ(0, status_handler.call_count());
}

TEST_F(PairingStateTest,
       JustWorksPairingIncomingConnectRequiresConfirmationRejectedResponder) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  FakePairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state.OnIoCapabilityResponse(IoCapability::NO_INPUT_NO_OUTPUT);
  ASSERT_FALSE(pairing_state.initiator());
  EXPECT_EQ(IoCapability::NO_INPUT_NO_OUTPUT,
            *pairing_state.OnIoCapabilityRequest());

  pairing_delegate.SetConfirmPairingCallback([this](PeerId peer_id, auto cb) {
    EXPECT_EQ(peer()->identifier(), peer_id);
    ASSERT_TRUE(cb);
    cb(false);
  });
  bool confirmed = true;
  pairing_state.OnUserConfirmationRequest(
      kTestPasskey, [&confirmed](bool confirm) { confirmed = confirm; });
  EXPECT_FALSE(confirmed);

  // Eventually the controller sends a SimplePairingComplete indicating the
  // failure.
  pairing_delegate.SetCompletePairingCallback(
      [this](PeerId peer_id, sm::Result<> status) {
        EXPECT_EQ(peer()->identifier(), peer_id);
        EXPECT_TRUE(status.is_error());
      });
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::AUTHENTICATION_FAILURE);

  EXPECT_EQ(1, status_handler.call_count());
  ASSERT_TRUE(status_handler.status());
  EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::AUTHENTICATION_FAILURE),
            *status_handler.status());
}

TEST_F(PairingStateTest,
       JustWorksPairingIncomingConnectRequiresConfirmationRejectedInitiator) {
  TestStatusHandler owner_status_handler;
  TestStatusHandler initiator_status_handler;
  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             owner_status_handler.MakeStatusCallback());

  FakePairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine to Initiator Waiting IOCap Request
  pairing_state.InitiatePairing(kNoSecurityRequirements,
                                initiator_status_handler.MakeStatusCallback());
  EXPECT_TRUE(pairing_state.initiator());
  static_cast<void>(pairing_state.OnLinkKeyRequest());
  EXPECT_EQ(IoCapability::NO_INPUT_NO_OUTPUT,
            *pairing_state.OnIoCapabilityRequest());

  pairing_state.OnIoCapabilityResponse(IoCapability::NO_INPUT_NO_OUTPUT);

  pairing_delegate.SetConfirmPairingCallback([this](PeerId peer_id, auto cb) {
    EXPECT_EQ(peer()->identifier(), peer_id);
    ASSERT_TRUE(cb);
    cb(false);
  });
  bool confirmed = true;
  pairing_state.OnUserConfirmationRequest(
      kTestPasskey, [&confirmed](bool confirm) { confirmed = confirm; });
  EXPECT_FALSE(confirmed);

  // Eventually the controller sends a SimplePairingComplete indicating the
  // failure.
  pairing_delegate.SetCompletePairingCallback(
      [this](PeerId peer_id, sm::Result<> status) {
        EXPECT_EQ(peer()->identifier(), peer_id);
        EXPECT_TRUE(status.is_error());
      });
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::AUTHENTICATION_FAILURE);

  EXPECT_EQ(1, owner_status_handler.call_count());
  ASSERT_TRUE(owner_status_handler.status());
  EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::AUTHENTICATION_FAILURE),
            *owner_status_handler.status());
  EXPECT_EQ(1, initiator_status_handler.call_count());
  ASSERT_TRUE(initiator_status_handler.status());
  EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::AUTHENTICATION_FAILURE),
            *initiator_status_handler.status());
}

TEST_F(PairingStateTest,
       JustWorksPairingIncomingConnectRequiresConfirmationAcceptedResponder) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  FakePairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state.OnIoCapabilityResponse(IoCapability::NO_INPUT_NO_OUTPUT);
  ASSERT_FALSE(pairing_state.initiator());
  EXPECT_EQ(IoCapability::NO_INPUT_NO_OUTPUT,
            *pairing_state.OnIoCapabilityRequest());

  pairing_delegate.SetConfirmPairingCallback([this](PeerId peer_id, auto cb) {
    EXPECT_EQ(peer()->identifier(), peer_id);
    ASSERT_TRUE(cb);
    cb(true);
  });
  bool confirmed = false;
  pairing_state.OnUserConfirmationRequest(
      kTestPasskey, [&confirmed](bool confirm) { confirmed = confirm; });
  EXPECT_TRUE(confirmed);

  pairing_delegate.SetCompletePairingCallback(
      [this](PeerId peer_id, sm::Result<> status) {
        EXPECT_EQ(peer()->identifier(), peer_id);
        EXPECT_EQ(fit::ok(), status);
      });
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);

  EXPECT_EQ(0, status_handler.call_count());
}

TEST_F(PairingStateTest,
       JustWorksPairingIncomingConnectRequiresConfirmationAcceptedInitiator) {
  TestStatusHandler owner_status_handler;
  TestStatusHandler initiator_status_handler;
  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             owner_status_handler.MakeStatusCallback());

  FakePairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine to Initiator Waiting IOCap Request
  pairing_state.InitiatePairing(kNoSecurityRequirements,
                                initiator_status_handler.MakeStatusCallback());
  EXPECT_TRUE(pairing_state.initiator());
  static_cast<void>(pairing_state.OnLinkKeyRequest());
  EXPECT_EQ(IoCapability::NO_INPUT_NO_OUTPUT,
            *pairing_state.OnIoCapabilityRequest());

  pairing_state.OnIoCapabilityResponse(IoCapability::NO_INPUT_NO_OUTPUT);

  pairing_delegate.SetConfirmPairingCallback([this](PeerId peer_id, auto cb) {
    EXPECT_EQ(peer()->identifier(), peer_id);
    ASSERT_TRUE(cb);
    cb(true);
  });
  bool confirmed = false;
  pairing_state.OnUserConfirmationRequest(
      kTestPasskey, [&confirmed](bool confirm) { confirmed = confirm; });
  EXPECT_TRUE(confirmed);

  pairing_delegate.SetCompletePairingCallback(
      [this](PeerId peer_id, sm::Result<> status) {
        EXPECT_EQ(peer()->identifier(), peer_id);
        EXPECT_EQ(fit::ok(), status);
      });
  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);

  EXPECT_EQ(0, owner_status_handler.call_count());
  EXPECT_EQ(0, initiator_status_handler.call_count());
}

// Event injectors. Return values are necessarily ignored in order to make types
// match, so don't use these functions to test return values. Likewise,
// arguments have been filled with test defaults for a successful pairing flow.
void LinkKeyRequest(PairingState* pairing_state) {
  static_cast<void>(pairing_state->OnLinkKeyRequest());
}
void IoCapabilityRequest(PairingState* pairing_state) {
  static_cast<void>(pairing_state->OnIoCapabilityRequest());
}
void IoCapabilityResponse(PairingState* pairing_state) {
  pairing_state->OnIoCapabilityResponse(kTestPeerIoCap);
}
void UserConfirmationRequest(PairingState* pairing_state) {
  pairing_state->OnUserConfirmationRequest(kTestPasskey,
                                           NoOpUserConfirmationCallback);
}
void UserPasskeyRequest(PairingState* pairing_state) {
  pairing_state->OnUserPasskeyRequest(NoOpUserPasskeyCallback);
}
void UserPasskeyNotification(PairingState* pairing_state) {
  pairing_state->OnUserPasskeyNotification(kTestPasskey);
}
void SimplePairingComplete(PairingState* pairing_state) {
  pairing_state->OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);
}
void LinkKeyNotification(PairingState* pairing_state) {
  pairing_state->OnLinkKeyNotification(kTestLinkKeyValue,
                                       kTestUnauthenticatedLinkKeyType192);
}
void AuthenticationComplete(PairingState* pairing_state) {
  pairing_state->OnAuthenticationComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);
}

// Test suite fixture that genericizes an injected pairing state event. The
// event being tested should be retrieved with the GetParam method, which
// returns a default event injector. For example:
//
//   PairingState pairing_state;
//   GetParam()(&pairing_state);
//
// This is named so that the instantiated test description looks correct:
//
//   PairingStateTest/HandlesEvent.<test case>/<index of event>
class HandlesEvent
    : public PairingStateTest,
      public ::testing::WithParamInterface<void (*)(PairingState*)> {
 public:
  void SetUp() override {
    PairingStateTest::SetUp();

    pairing_delegate_ = std::make_unique<NoOpPairingDelegate>(kTestLocalIoCap);
    pairing_state_ =
        std::make_unique<PairingState>(peer()->GetWeakPtr(),
                                       connection(),
                                       /*link_initiated=*/false,
                                       MakeAuthRequestCallback(),
                                       status_handler_.MakeStatusCallback());
    pairing_state().SetPairingDelegate(pairing_delegate_->GetWeakPtr());
  }

  void TearDown() override {
    pairing_state_.reset();
    PairingStateTest::TearDown();
  }

  const TestStatusHandler& status_handler() const { return status_handler_; }
  PairingState& pairing_state() { return *pairing_state_; }

  // Returns an event injector that was passed to INSTANTIATE_TEST_SUITE_P.
  auto* event() const { return GetParam(); }

  void InjectEvent() { event()(&pairing_state()); }

 private:
  TestStatusHandler status_handler_;
  std::unique_ptr<NoOpPairingDelegate> pairing_delegate_;
  std::unique_ptr<PairingState> pairing_state_;
};

// The tests here exercise that PairingState can be successfully advances
// through the expected pairing flow and generates errors when the pairing flow
// occurs out of order. This is intended to cover its internal state machine
// transitions and not the side effects.
INSTANTIATE_TEST_SUITE_P(PairingStateTest,
                         HandlesEvent,
                         ::testing::Values(LinkKeyRequest,
                                           IoCapabilityRequest,
                                           IoCapabilityResponse,
                                           UserConfirmationRequest,
                                           UserPasskeyRequest,
                                           UserPasskeyNotification,
                                           SimplePairingComplete,
                                           LinkKeyNotification,
                                           AuthenticationComplete));

TEST_P(HandlesEvent, InIdleState) {
  RETURN_IF_FATAL(InjectEvent());
  if (event() == LinkKeyRequest || event() == IoCapabilityResponse) {
    EXPECT_EQ(0, status_handler().call_count());
  } else {
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().handle());
    EXPECT_EQ(kTestHandle, *status_handler().handle());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InInitiatorWaitLinkKeyRequestState) {
  // Advance state machine.
  static_cast<void>(pairing_state().InitiatePairing(kNoSecurityRequirements,
                                                    NoOpStatusCallback));

  RETURN_IF_FATAL(InjectEvent());
  if (event() == LinkKeyRequest) {
    EXPECT_EQ(0, status_handler().call_count());
  } else {
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InInitiatorWaitIoCapRequest) {
  // Advance state machine.
  pairing_state().InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);
  static_cast<void>(pairing_state().OnLinkKeyRequest());

  RETURN_IF_FATAL(InjectEvent());
  if (event() == IoCapabilityRequest) {
    EXPECT_EQ(0, status_handler().call_count());
  } else {
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InInitiatorWaitAuthCompleteSkippingSimplePairing) {
  peer()->MutBrEdr().SetBondData(
      sm::LTK(sm::SecurityProperties(kTestUnauthenticatedLinkKeyType192),
              kTestLinkKey));

  // Advance state machine.
  pairing_state().InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);
  EXPECT_NE(std::nullopt, pairing_state().OnLinkKeyRequest());

  RETURN_IF_FATAL(InjectEvent());
  if (event() == AuthenticationComplete) {
    EXPECT_EQ(0, status_handler().call_count());
    EXPECT_EQ(1, connection()->start_encryption_count());
  } else {
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InInitiatorWaitIoCapResponseState) {
  // Advance state machine.
  static_cast<void>(pairing_state().InitiatePairing(kNoSecurityRequirements,
                                                    NoOpStatusCallback));
  static_cast<void>(pairing_state().OnLinkKeyRequest());
  static_cast<void>(pairing_state().OnIoCapabilityRequest());

  RETURN_IF_FATAL(InjectEvent());
  if (event() == IoCapabilityResponse) {
    EXPECT_EQ(0, status_handler().call_count());
  } else {
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InResponderWaitIoCapRequestState) {
  // Advance state machine.
  pairing_state().OnIoCapabilityResponse(kTestPeerIoCap);

  RETURN_IF_FATAL(InjectEvent());
  if (event() == IoCapabilityRequest) {
    EXPECT_EQ(0, status_handler().call_count());
  } else {
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent,
       InErrorStateAfterIoCapRequestRejectedWithoutPairingDelegate) {
  // Clear the default pairing delegate set by the fixture.
  pairing_state().SetPairingDelegate(PairingDelegate::WeakPtr());

  // Advance state machine.
  pairing_state().OnIoCapabilityResponse(kTestPeerIoCap);
  EXPECT_FALSE(pairing_state().OnIoCapabilityRequest());

  // PairingState no longer accepts events because being not ready to pair has
  // raised an error.
  RETURN_IF_FATAL(InjectEvent());
  EXPECT_LE(1, status_handler().call_count());
  ASSERT_TRUE(status_handler().status());
  if (event() == LinkKeyRequest || event() == IoCapabilityResponse) {
    // Peer attempted to pair again, which raises an additional "not ready"
    // error.
    EXPECT_EQ(ToResult(HostError::kNotReady), status_handler().status());
  } else {
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InWaitUserConfirmationStateAsInitiator) {
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kDisplayOnly);
  pairing_state().SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state().InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);
  static_cast<void>(pairing_state().OnLinkKeyRequest());
  static_cast<void>(pairing_state().OnIoCapabilityRequest());
  pairing_state().OnIoCapabilityResponse(IoCapability::DISPLAY_YES_NO);
  ASSERT_TRUE(pairing_state().initiator());

  RETURN_IF_FATAL(InjectEvent());
  if (event() == UserConfirmationRequest) {
    EXPECT_EQ(0, status_handler().call_count());
  } else {
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InWaitUserPasskeyRequestStateAsInitiator) {
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kKeyboardOnly);
  pairing_state().SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state().InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);
  static_cast<void>(pairing_state().OnLinkKeyRequest());
  static_cast<void>(pairing_state().OnIoCapabilityRequest());
  pairing_state().OnIoCapabilityResponse(IoCapability::DISPLAY_ONLY);
  ASSERT_TRUE(pairing_state().initiator());

  RETURN_IF_FATAL(InjectEvent());
  if (event() == UserPasskeyRequest) {
    EXPECT_EQ(0, status_handler().call_count());
  } else {
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InWaitUserPasskeyNotificationStateAsInitiator) {
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kDisplayOnly);
  pairing_state().SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state().InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);
  static_cast<void>(pairing_state().OnLinkKeyRequest());
  static_cast<void>(pairing_state().OnIoCapabilityRequest());
  pairing_state().OnIoCapabilityResponse(IoCapability::KEYBOARD_ONLY);
  ASSERT_TRUE(pairing_state().initiator());

  RETURN_IF_FATAL(InjectEvent());
  if (event() == UserPasskeyNotification) {
    EXPECT_EQ(0, status_handler().call_count());
  } else {
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

// TODO(xow): Split into three tests depending on the pairing event expected.
TEST_P(HandlesEvent, InWaitUserConfirmationStateAsResponder) {
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kDisplayOnly);
  pairing_state().SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state().OnIoCapabilityResponse(IoCapability::DISPLAY_YES_NO);
  static_cast<void>(pairing_state().OnIoCapabilityRequest());
  ASSERT_FALSE(pairing_state().initiator());

  RETURN_IF_FATAL(InjectEvent());
  if (event() == UserConfirmationRequest) {
    EXPECT_EQ(0, status_handler().call_count());
  } else {
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InWaitUserPasskeyRequestStateAsResponder) {
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kKeyboardOnly);
  pairing_state().SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state().OnIoCapabilityResponse(IoCapability::DISPLAY_ONLY);
  static_cast<void>(pairing_state().OnIoCapabilityRequest());
  ASSERT_FALSE(pairing_state().initiator());

  RETURN_IF_FATAL(InjectEvent());
  if (event() == UserPasskeyRequest) {
    EXPECT_EQ(0, status_handler().call_count());
  } else {
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InWaitUserNotificationStateAsResponder) {
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kDisplayOnly);
  pairing_state().SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Advance state machine.
  pairing_state().OnIoCapabilityResponse(IoCapability::KEYBOARD_ONLY);
  static_cast<void>(pairing_state().OnIoCapabilityRequest());
  ASSERT_FALSE(pairing_state().initiator());

  RETURN_IF_FATAL(InjectEvent());
  if (event() == UserPasskeyNotification) {
    EXPECT_EQ(0, status_handler().call_count());
  } else {
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InWaitPairingCompleteState) {
  // Advance state machine.
  pairing_state().OnIoCapabilityResponse(kTestPeerIoCap);
  static_cast<void>(pairing_state().OnIoCapabilityRequest());
  pairing_state().OnUserConfirmationRequest(kTestPasskey,
                                            NoOpUserConfirmationCallback);

  RETURN_IF_FATAL(InjectEvent());
  if (event() == SimplePairingComplete) {
    EXPECT_EQ(0, status_handler().call_count());
  } else {
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InWaitLinkKeyState) {
  // Advance state machine.
  pairing_state().OnIoCapabilityResponse(kTestPeerIoCap);
  static_cast<void>(pairing_state().OnIoCapabilityRequest());
  pairing_state().OnUserConfirmationRequest(kTestPasskey,
                                            NoOpUserConfirmationCallback);
  pairing_state().OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  EXPECT_EQ(0, connection()->start_encryption_count());

  RETURN_IF_FATAL(InjectEvent());
  if (event() == LinkKeyNotification) {
    EXPECT_EQ(0, status_handler().call_count());
    EXPECT_EQ(1, connection()->start_encryption_count());
  } else {
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InInitiatorWaitAuthCompleteStateAfterSimplePairing) {
  // Advance state machine.
  pairing_state().InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);
  static_cast<void>(pairing_state().OnLinkKeyRequest());
  static_cast<void>(pairing_state().OnIoCapabilityRequest());
  pairing_state().OnIoCapabilityResponse(kTestPeerIoCap);
  pairing_state().OnUserConfirmationRequest(kTestPasskey,
                                            NoOpUserConfirmationCallback);
  pairing_state().OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  pairing_state().OnLinkKeyNotification(kTestLinkKeyValue,
                                        kTestUnauthenticatedLinkKeyType192);
  ASSERT_TRUE(pairing_state().initiator());
  EXPECT_EQ(0, connection()->start_encryption_count());

  RETURN_IF_FATAL(InjectEvent());
  if (event() == AuthenticationComplete) {
    EXPECT_EQ(0, status_handler().call_count());
    EXPECT_EQ(1, connection()->start_encryption_count());
  } else {
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InWaitEncryptionStateAsInitiator) {
  // Advance state machine.
  pairing_state().InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);
  static_cast<void>(pairing_state().OnLinkKeyRequest());
  static_cast<void>(pairing_state().OnIoCapabilityRequest());
  pairing_state().OnIoCapabilityResponse(kTestPeerIoCap);
  pairing_state().OnUserConfirmationRequest(kTestPasskey,
                                            NoOpUserConfirmationCallback);
  pairing_state().OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  pairing_state().OnLinkKeyNotification(kTestLinkKeyValue,
                                        kTestUnauthenticatedLinkKeyType192);
  pairing_state().OnAuthenticationComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  ASSERT_TRUE(pairing_state().initiator());

  RETURN_IF_FATAL(InjectEvent());

  if (event() == IoCapabilityResponse) {
    // Restarting the pairing is allowed in this state.
    EXPECT_EQ(0, status_handler().call_count());
  } else {
    // Should not receive anything else other than OnEncryptionChange.
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InWaitEncryptionStateAsResponder) {
  // Advance state machine.
  pairing_state().OnIoCapabilityResponse(kTestPeerIoCap);
  static_cast<void>(pairing_state().OnIoCapabilityRequest());
  pairing_state().OnUserConfirmationRequest(kTestPasskey,
                                            NoOpUserConfirmationCallback);
  pairing_state().OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  pairing_state().OnLinkKeyNotification(kTestLinkKeyValue,
                                        kTestUnauthenticatedLinkKeyType192);
  ASSERT_FALSE(pairing_state().initiator());

  RETURN_IF_FATAL(InjectEvent());

  if (event() == IoCapabilityResponse) {
    // Restarting the pairing is allowed in this state.
    EXPECT_EQ(0, status_handler().call_count());
  } else {
    // Should not receive anything else other than OnEncryptionChange.
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InWaitEncryptionStateAsResponderForBonded) {
  // We are previously bonded.
  auto existing_link_key = sm::LTK(
      sm::SecurityProperties(kTestUnauthenticatedLinkKeyType192), kTestLinkKey);
  peer()->MutBrEdr().SetBondData(existing_link_key);

  // Advance state machine.
  static_cast<void>(pairing_state().OnLinkKeyRequest());
  ASSERT_FALSE(pairing_state().initiator());

  RETURN_IF_FATAL(InjectEvent());

  if (event() == IoCapabilityResponse) {
    // This re-starts the pairing as a responder.
    EXPECT_EQ(0, status_handler().call_count());
  } else {
    // Should not receive anything else other than OnEncryptionChange, receiving
    // anything else is a failure.
    EXPECT_EQ(1, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InIdleStateAfterOnePairing) {
  // Advance state machine.
  static_cast<void>(pairing_state().InitiatePairing(kNoSecurityRequirements,
                                                    NoOpStatusCallback));
  static_cast<void>(pairing_state().OnLinkKeyRequest());
  static_cast<void>(pairing_state().OnIoCapabilityRequest());
  pairing_state().OnIoCapabilityResponse(kTestPeerIoCap);
  pairing_state().OnUserConfirmationRequest(kTestPasskey,
                                            NoOpUserConfirmationCallback);
  pairing_state().OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  pairing_state().OnLinkKeyNotification(kTestLinkKeyValue,
                                        kTestUnauthenticatedLinkKeyType192);
  pairing_state().OnAuthenticationComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  ASSERT_TRUE(pairing_state().initiator());

  // Successfully enabling encryption should allow pairing to start again.
  pairing_state().OnEncryptionChange(fit::ok(true));
  EXPECT_EQ(1, status_handler().call_count());
  ASSERT_TRUE(status_handler().status());
  EXPECT_EQ(fit::ok(), *status_handler().status());
  EXPECT_FALSE(pairing_state().initiator());

  RETURN_IF_FATAL(InjectEvent());
  if (event() == LinkKeyRequest || event() == IoCapabilityResponse) {
    EXPECT_EQ(1, status_handler().call_count());
  } else {
    EXPECT_EQ(2, status_handler().call_count());
    ASSERT_TRUE(status_handler().status());
    EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
  }
}

TEST_P(HandlesEvent, InFailedStateAfterPairingFailed) {
  // Advance state machine.
  pairing_state().OnIoCapabilityResponse(kTestPeerIoCap);
  static_cast<void>(pairing_state().OnIoCapabilityRequest());
  pairing_state().OnUserConfirmationRequest(kTestPasskey,
                                            NoOpUserConfirmationCallback);

  // Inject failure status.
  pairing_state().OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::AUTHENTICATION_FAILURE);
  EXPECT_EQ(1, status_handler().call_count());
  ASSERT_TRUE(status_handler().status());
  EXPECT_FALSE(status_handler().status()->is_ok());

  RETURN_IF_FATAL(InjectEvent());
  EXPECT_EQ(2, status_handler().call_count());
  ASSERT_TRUE(status_handler().status());
  EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
}

TEST_P(HandlesEvent, InFailedStateAfterAuthenticationFailed) {
  // Advance state machine.
  static_cast<void>(pairing_state().InitiatePairing(kNoSecurityRequirements,
                                                    NoOpStatusCallback));
  static_cast<void>(pairing_state().OnLinkKeyRequest());
  static_cast<void>(pairing_state().OnIoCapabilityRequest());
  pairing_state().OnIoCapabilityResponse(kTestPeerIoCap);
  pairing_state().OnUserConfirmationRequest(kTestPasskey,
                                            NoOpUserConfirmationCallback);
  pairing_state().OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  pairing_state().OnLinkKeyNotification(kTestLinkKeyValue,
                                        kTestUnauthenticatedLinkKeyType192);

  // Inject failure status.
  pairing_state().OnAuthenticationComplete(
      pw::bluetooth::emboss::StatusCode::AUTHENTICATION_FAILURE);
  EXPECT_EQ(1, status_handler().call_count());
  ASSERT_TRUE(status_handler().status());
  EXPECT_FALSE(status_handler().status()->is_ok());

  RETURN_IF_FATAL(InjectEvent());
  EXPECT_EQ(2, status_handler().call_count());
  ASSERT_TRUE(status_handler().status());
  EXPECT_EQ(ToResult(HostError::kNotSupported), status_handler().status());
}

// PairingAction expected answers are inferred from "device A" Authentication
// Stage 1 specs in v5.0 Vol 3, Part C, Sec 5.2.2.6, Table 5.7.
TEST_F(PairingStateTest, GetInitiatorPairingAction) {
  EXPECT_EQ(PairingAction::kAutomatic,
            GetInitiatorPairingAction(IoCapability::DISPLAY_ONLY,
                                      IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(PairingAction::kDisplayPasskey,
            GetInitiatorPairingAction(IoCapability::DISPLAY_ONLY,
                                      IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(PairingAction::kDisplayPasskey,
            GetInitiatorPairingAction(IoCapability::DISPLAY_ONLY,
                                      IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(PairingAction::kAutomatic,
            GetInitiatorPairingAction(IoCapability::DISPLAY_ONLY,
                                      IoCapability::NO_INPUT_NO_OUTPUT));

  EXPECT_EQ(PairingAction::kComparePasskey,
            GetInitiatorPairingAction(IoCapability::DISPLAY_YES_NO,
                                      IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(PairingAction::kDisplayPasskey,
            GetInitiatorPairingAction(IoCapability::DISPLAY_YES_NO,
                                      IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(PairingAction::kDisplayPasskey,
            GetInitiatorPairingAction(IoCapability::DISPLAY_YES_NO,
                                      IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(PairingAction::kGetConsent,
            GetInitiatorPairingAction(IoCapability::DISPLAY_YES_NO,
                                      IoCapability::NO_INPUT_NO_OUTPUT));

  EXPECT_EQ(PairingAction::kRequestPasskey,
            GetInitiatorPairingAction(IoCapability::KEYBOARD_ONLY,
                                      IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(PairingAction::kRequestPasskey,
            GetInitiatorPairingAction(IoCapability::KEYBOARD_ONLY,
                                      IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(PairingAction::kRequestPasskey,
            GetInitiatorPairingAction(IoCapability::KEYBOARD_ONLY,
                                      IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(PairingAction::kAutomatic,
            GetInitiatorPairingAction(IoCapability::KEYBOARD_ONLY,
                                      IoCapability::NO_INPUT_NO_OUTPUT));

  EXPECT_EQ(PairingAction::kAutomatic,
            GetInitiatorPairingAction(IoCapability::NO_INPUT_NO_OUTPUT,
                                      IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(PairingAction::kAutomatic,
            GetInitiatorPairingAction(IoCapability::NO_INPUT_NO_OUTPUT,
                                      IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(PairingAction::kAutomatic,
            GetInitiatorPairingAction(IoCapability::NO_INPUT_NO_OUTPUT,
                                      IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(PairingAction::kAutomatic,
            GetInitiatorPairingAction(IoCapability::NO_INPUT_NO_OUTPUT,
                                      IoCapability::NO_INPUT_NO_OUTPUT));
}

// Ibid., but for "device B."
TEST_F(PairingStateTest, GetResponderPairingAction) {
  EXPECT_EQ(PairingAction::kAutomatic,
            GetResponderPairingAction(IoCapability::DISPLAY_ONLY,
                                      IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(PairingAction::kComparePasskey,
            GetResponderPairingAction(IoCapability::DISPLAY_ONLY,
                                      IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(PairingAction::kRequestPasskey,
            GetResponderPairingAction(IoCapability::DISPLAY_ONLY,
                                      IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(PairingAction::kAutomatic,
            GetResponderPairingAction(IoCapability::DISPLAY_ONLY,
                                      IoCapability::NO_INPUT_NO_OUTPUT));

  EXPECT_EQ(PairingAction::kDisplayPasskey,
            GetResponderPairingAction(IoCapability::DISPLAY_YES_NO,
                                      IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(PairingAction::kComparePasskey,
            GetResponderPairingAction(IoCapability::DISPLAY_YES_NO,
                                      IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(PairingAction::kRequestPasskey,
            GetResponderPairingAction(IoCapability::DISPLAY_YES_NO,
                                      IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(PairingAction::kAutomatic,
            GetResponderPairingAction(IoCapability::DISPLAY_YES_NO,
                                      IoCapability::NO_INPUT_NO_OUTPUT));

  EXPECT_EQ(PairingAction::kDisplayPasskey,
            GetResponderPairingAction(IoCapability::KEYBOARD_ONLY,
                                      IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(PairingAction::kDisplayPasskey,
            GetResponderPairingAction(IoCapability::KEYBOARD_ONLY,
                                      IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(PairingAction::kRequestPasskey,
            GetResponderPairingAction(IoCapability::KEYBOARD_ONLY,
                                      IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(PairingAction::kAutomatic,
            GetResponderPairingAction(IoCapability::KEYBOARD_ONLY,
                                      IoCapability::NO_INPUT_NO_OUTPUT));

  EXPECT_EQ(PairingAction::kAutomatic,
            GetResponderPairingAction(IoCapability::NO_INPUT_NO_OUTPUT,
                                      IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(PairingAction::kGetConsent,
            GetResponderPairingAction(IoCapability::NO_INPUT_NO_OUTPUT,
                                      IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(PairingAction::kGetConsent,
            GetResponderPairingAction(IoCapability::NO_INPUT_NO_OUTPUT,
                                      IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(PairingAction::kAutomatic,
            GetResponderPairingAction(IoCapability::NO_INPUT_NO_OUTPUT,
                                      IoCapability::NO_INPUT_NO_OUTPUT));
}

// Events are obtained from ibid. association models, mapped to HCI sequences in
// v5.0 Vol 3, Vol 2, Part F, Sec 4.2.10–15.
TEST_F(PairingStateTest, GetExpectedEvent) {
  EXPECT_EQ(
      kUserConfirmationRequestEventCode,
      GetExpectedEvent(IoCapability::DISPLAY_ONLY, IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(kUserConfirmationRequestEventCode,
            GetExpectedEvent(IoCapability::DISPLAY_ONLY,
                             IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(kUserPasskeyNotificationEventCode,
            GetExpectedEvent(IoCapability::DISPLAY_ONLY,
                             IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(kUserConfirmationRequestEventCode,
            GetExpectedEvent(IoCapability::DISPLAY_ONLY,
                             IoCapability::NO_INPUT_NO_OUTPUT));

  EXPECT_EQ(kUserConfirmationRequestEventCode,
            GetExpectedEvent(IoCapability::DISPLAY_YES_NO,
                             IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(kUserConfirmationRequestEventCode,
            GetExpectedEvent(IoCapability::DISPLAY_YES_NO,
                             IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(kUserPasskeyNotificationEventCode,
            GetExpectedEvent(IoCapability::DISPLAY_YES_NO,
                             IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(kUserConfirmationRequestEventCode,
            GetExpectedEvent(IoCapability::DISPLAY_YES_NO,
                             IoCapability::NO_INPUT_NO_OUTPUT));

  EXPECT_EQ(kUserPasskeyRequestEventCode,
            GetExpectedEvent(IoCapability::KEYBOARD_ONLY,
                             IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(kUserPasskeyRequestEventCode,
            GetExpectedEvent(IoCapability::KEYBOARD_ONLY,
                             IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(kUserPasskeyRequestEventCode,
            GetExpectedEvent(IoCapability::KEYBOARD_ONLY,
                             IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(kUserConfirmationRequestEventCode,
            GetExpectedEvent(IoCapability::KEYBOARD_ONLY,
                             IoCapability::NO_INPUT_NO_OUTPUT));

  EXPECT_EQ(kUserConfirmationRequestEventCode,
            GetExpectedEvent(IoCapability::NO_INPUT_NO_OUTPUT,
                             IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(kUserConfirmationRequestEventCode,
            GetExpectedEvent(IoCapability::NO_INPUT_NO_OUTPUT,
                             IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(kUserConfirmationRequestEventCode,
            GetExpectedEvent(IoCapability::NO_INPUT_NO_OUTPUT,
                             IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(kUserConfirmationRequestEventCode,
            GetExpectedEvent(IoCapability::NO_INPUT_NO_OUTPUT,
                             IoCapability::NO_INPUT_NO_OUTPUT));
}

// Level of authentication from ibid. table.
TEST_F(PairingStateTest, IsPairingAuthenticated) {
  EXPECT_FALSE(IsPairingAuthenticated(IoCapability::DISPLAY_ONLY,
                                      IoCapability::DISPLAY_ONLY));
  EXPECT_FALSE(IsPairingAuthenticated(IoCapability::DISPLAY_ONLY,
                                      IoCapability::DISPLAY_YES_NO));
  EXPECT_TRUE(IsPairingAuthenticated(IoCapability::DISPLAY_ONLY,
                                     IoCapability::KEYBOARD_ONLY));
  EXPECT_FALSE(IsPairingAuthenticated(IoCapability::DISPLAY_ONLY,
                                      IoCapability::NO_INPUT_NO_OUTPUT));

  EXPECT_FALSE(IsPairingAuthenticated(IoCapability::DISPLAY_YES_NO,
                                      IoCapability::DISPLAY_ONLY));
  EXPECT_TRUE(IsPairingAuthenticated(IoCapability::DISPLAY_YES_NO,
                                     IoCapability::DISPLAY_YES_NO));
  EXPECT_TRUE(IsPairingAuthenticated(IoCapability::DISPLAY_YES_NO,
                                     IoCapability::KEYBOARD_ONLY));
  EXPECT_FALSE(IsPairingAuthenticated(IoCapability::DISPLAY_YES_NO,
                                      IoCapability::NO_INPUT_NO_OUTPUT));

  EXPECT_TRUE(IsPairingAuthenticated(IoCapability::KEYBOARD_ONLY,
                                     IoCapability::DISPLAY_ONLY));
  EXPECT_TRUE(IsPairingAuthenticated(IoCapability::KEYBOARD_ONLY,
                                     IoCapability::DISPLAY_YES_NO));
  EXPECT_TRUE(IsPairingAuthenticated(IoCapability::KEYBOARD_ONLY,
                                     IoCapability::KEYBOARD_ONLY));
  EXPECT_FALSE(IsPairingAuthenticated(IoCapability::KEYBOARD_ONLY,
                                      IoCapability::NO_INPUT_NO_OUTPUT));

  EXPECT_FALSE(IsPairingAuthenticated(IoCapability::NO_INPUT_NO_OUTPUT,
                                      IoCapability::DISPLAY_ONLY));
  EXPECT_FALSE(IsPairingAuthenticated(IoCapability::NO_INPUT_NO_OUTPUT,
                                      IoCapability::DISPLAY_YES_NO));
  EXPECT_FALSE(IsPairingAuthenticated(IoCapability::NO_INPUT_NO_OUTPUT,
                                      IoCapability::KEYBOARD_ONLY));
  EXPECT_FALSE(IsPairingAuthenticated(IoCapability::NO_INPUT_NO_OUTPUT,
                                      IoCapability::NO_INPUT_NO_OUTPUT));
}

TEST_F(PairingStateTest, GetInitiatorAuthenticationRequirements) {
  EXPECT_EQ(AuthenticationRequirements::MITM_GENERAL_BONDING,
            GetInitiatorAuthenticationRequirements(IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(
      AuthenticationRequirements::MITM_GENERAL_BONDING,
      GetInitiatorAuthenticationRequirements(IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(
      AuthenticationRequirements::MITM_GENERAL_BONDING,
      GetInitiatorAuthenticationRequirements(IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(
      AuthenticationRequirements::GENERAL_BONDING,
      GetInitiatorAuthenticationRequirements(IoCapability::NO_INPUT_NO_OUTPUT));
}

TEST_F(PairingStateTest, GetResponderAuthenticationRequirements) {
  EXPECT_EQ(AuthenticationRequirements::GENERAL_BONDING,
            GetResponderAuthenticationRequirements(IoCapability::DISPLAY_ONLY,
                                                   IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(AuthenticationRequirements::GENERAL_BONDING,
            GetResponderAuthenticationRequirements(
                IoCapability::DISPLAY_ONLY, IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(AuthenticationRequirements::MITM_GENERAL_BONDING,
            GetResponderAuthenticationRequirements(
                IoCapability::DISPLAY_ONLY, IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(AuthenticationRequirements::GENERAL_BONDING,
            GetResponderAuthenticationRequirements(
                IoCapability::DISPLAY_ONLY, IoCapability::NO_INPUT_NO_OUTPUT));

  EXPECT_EQ(AuthenticationRequirements::GENERAL_BONDING,
            GetResponderAuthenticationRequirements(IoCapability::DISPLAY_YES_NO,
                                                   IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(AuthenticationRequirements::MITM_GENERAL_BONDING,
            GetResponderAuthenticationRequirements(
                IoCapability::DISPLAY_YES_NO, IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(AuthenticationRequirements::MITM_GENERAL_BONDING,
            GetResponderAuthenticationRequirements(
                IoCapability::DISPLAY_YES_NO, IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(
      AuthenticationRequirements::GENERAL_BONDING,
      GetResponderAuthenticationRequirements(IoCapability::DISPLAY_YES_NO,
                                             IoCapability::NO_INPUT_NO_OUTPUT));

  EXPECT_EQ(AuthenticationRequirements::MITM_GENERAL_BONDING,
            GetResponderAuthenticationRequirements(IoCapability::KEYBOARD_ONLY,
                                                   IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(AuthenticationRequirements::MITM_GENERAL_BONDING,
            GetResponderAuthenticationRequirements(
                IoCapability::KEYBOARD_ONLY, IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(AuthenticationRequirements::MITM_GENERAL_BONDING,
            GetResponderAuthenticationRequirements(
                IoCapability::KEYBOARD_ONLY, IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(AuthenticationRequirements::GENERAL_BONDING,
            GetResponderAuthenticationRequirements(
                IoCapability::KEYBOARD_ONLY, IoCapability::NO_INPUT_NO_OUTPUT));

  EXPECT_EQ(AuthenticationRequirements::GENERAL_BONDING,
            GetResponderAuthenticationRequirements(
                IoCapability::NO_INPUT_NO_OUTPUT, IoCapability::DISPLAY_ONLY));
  EXPECT_EQ(
      AuthenticationRequirements::GENERAL_BONDING,
      GetResponderAuthenticationRequirements(IoCapability::NO_INPUT_NO_OUTPUT,
                                             IoCapability::DISPLAY_YES_NO));
  EXPECT_EQ(AuthenticationRequirements::GENERAL_BONDING,
            GetResponderAuthenticationRequirements(
                IoCapability::NO_INPUT_NO_OUTPUT, IoCapability::KEYBOARD_ONLY));
  EXPECT_EQ(
      AuthenticationRequirements::GENERAL_BONDING,
      GetResponderAuthenticationRequirements(IoCapability::NO_INPUT_NO_OUTPUT,
                                             IoCapability::NO_INPUT_NO_OUTPUT));
}

TEST_F(PairingStateTest, SkipPairingIfExistingKeyMeetsSecurityRequirements) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  connection()->set_link_key(kTestLinkKey, kTestAuthenticatedLinkKeyType192);

  constexpr BrEdrSecurityRequirements kSecurityRequirements{
      .authentication = true, .secure_connections = false};
  TestStatusHandler initiator_status_handler;
  pairing_state.InitiatePairing(kSecurityRequirements,
                                initiator_status_handler.MakeStatusCallback());
  EXPECT_EQ(0u, auth_request_count());
  EXPECT_FALSE(pairing_state.initiator());
  EXPECT_EQ(0, status_handler.call_count());
  ASSERT_EQ(1, initiator_status_handler.call_count());
  EXPECT_EQ(fit::ok(), *initiator_status_handler.status());
}

TEST_F(
    PairingStateTest,
    InitiatorAuthRequiredCausesOnLinkKeyRequestToReturnNullIfUnauthenticatedKeyExists) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  BrEdrSecurityRequirements security{.authentication = true,
                                     .secure_connections = false};
  pairing_state.InitiatePairing(security, status_handler.MakeStatusCallback());

  peer()->MutBrEdr().SetBondData(
      sm::LTK(sm::SecurityProperties(kTestUnauthenticatedLinkKeyType192),
              kTestLinkKey));

  EXPECT_EQ(std::nullopt, pairing_state.OnLinkKeyRequest());
  EXPECT_EQ(0, status_handler.call_count());
}

TEST_F(
    PairingStateTest,
    InitiatorNoSecurityRequirementsCausesOnLinkKeyRequestToReturnExistingKey) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  pairing_state.InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);

  peer()->MutBrEdr().SetBondData(
      sm::LTK(sm::SecurityProperties(kTestUnauthenticatedLinkKeyType192),
              kTestLinkKey));
  EXPECT_FALSE(connection()->ltk().has_value());

  auto reply_key = pairing_state.OnLinkKeyRequest();
  ASSERT_TRUE(reply_key.has_value());
  EXPECT_EQ(kTestLinkKey, reply_key.value());
  EXPECT_EQ(0, status_handler.call_count());
  EXPECT_TRUE(connection()->ltk().has_value());
}

TEST_F(PairingStateTest,
       InitiatorOnLinkKeyRequestReturnsNullIfBondDataDoesNotExist) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  pairing_state.InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);

  auto reply_key = pairing_state.OnLinkKeyRequest();
  EXPECT_FALSE(reply_key.has_value());
  EXPECT_EQ(0, status_handler.call_count());
}

TEST_F(PairingStateTest,
       IdleStateOnLinkKeyRequestReturnsLinkKeyWhenBondDataExists) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  peer()->MutBrEdr().SetBondData(
      sm::LTK(sm::SecurityProperties(kTestUnauthenticatedLinkKeyType192),
              kTestLinkKey));
  EXPECT_FALSE(connection()->ltk().has_value());

  auto reply_key = pairing_state.OnLinkKeyRequest();
  ASSERT_TRUE(reply_key.has_value());
  EXPECT_EQ(kTestLinkKey, reply_key.value());
  EXPECT_EQ(0, status_handler.call_count());
  EXPECT_TRUE(connection()->ltk().has_value());
}

TEST_F(PairingStateTest,
       IdleStateOnLinkKeyRequestReturnsNullWhenBondDataDoesNotExist) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  auto reply_key = pairing_state.OnLinkKeyRequest();
  EXPECT_FALSE(reply_key.has_value());
  EXPECT_EQ(0, status_handler.call_count());
}

TEST_F(PairingStateTest,
       SimplePairingCompleteWithErrorCodeReceivedEarlyFailsPairing) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  pairing_state.InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);

  EXPECT_EQ(std::nullopt, pairing_state.OnLinkKeyRequest());
  EXPECT_EQ(IoCapability::NO_INPUT_NO_OUTPUT,
            *pairing_state.OnIoCapabilityRequest());
  EXPECT_EQ(0, status_handler.call_count());

  const auto status_code =
      pw::bluetooth::emboss::StatusCode::PAIRING_NOT_ALLOWED;
  pairing_state.OnSimplePairingComplete(status_code);
  ASSERT_EQ(1, status_handler.call_count());
  EXPECT_EQ(ToResult(status_code), status_handler.status().value());
}

TEST_F(PairingStateDeathTest, OnLinkKeyRequestReceivedMissingPeerAsserts) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  pairing_state.InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);

  EXPECT_TRUE(peer_cache()->RemoveDisconnectedPeer(peer()->identifier()));

  ASSERT_DEATH_IF_SUPPORTED(
      { [[maybe_unused]] auto reply_key = pairing_state.OnLinkKeyRequest(); },
      ".*peer.*");
}

TEST_F(PairingStateTest,
       AuthenticationCompleteWithErrorCodeReceivedEarlyFailsPairing) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  pairing_state.InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);

  EXPECT_EQ(std::nullopt, pairing_state.OnLinkKeyRequest());
  EXPECT_EQ(0, status_handler.call_count());

  const auto status_code =
      pw::bluetooth::emboss::StatusCode::AUTHENTICATION_FAILURE;
  pairing_state.OnAuthenticationComplete(status_code);
  ASSERT_EQ(1, status_handler.call_count());
  EXPECT_EQ(ToResult(status_code), status_handler.status().value());
}

TEST_F(
    PairingStateTest,
    AuthenticationCompleteWithMissingKeyRetriesWithoutKeyAndDoesntAutoConfirmRejected) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/true,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  FakePairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  auto existing_link_key = sm::LTK(
      sm::SecurityProperties(kTestUnauthenticatedLinkKeyType192), kTestLinkKey);

  peer()->MutBrEdr().SetBondData(existing_link_key);
  EXPECT_FALSE(connection()->ltk().has_value());

  pairing_state.InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);
  EXPECT_EQ(1u, auth_request_count());

  auto reply_key = pairing_state.OnLinkKeyRequest();
  ASSERT_TRUE(reply_key.has_value());
  EXPECT_EQ(kTestLinkKey, reply_key.value());
  EXPECT_EQ(0, status_handler.call_count());

  // Peer says that they don't have a key.
  pairing_state.OnAuthenticationComplete(
      pw::bluetooth::emboss::StatusCode::PIN_OR_KEY_MISSING);
  ASSERT_EQ(0, status_handler.call_count());
  // We should retry the authentication request, this time pretending we don't
  // have a key.
  EXPECT_EQ(2u, auth_request_count());

  EXPECT_EQ(std::nullopt, pairing_state.OnLinkKeyRequest());
  EXPECT_EQ(0, status_handler.call_count());

  static_cast<void>(pairing_state.OnIoCapabilityRequest());
  pairing_state.OnIoCapabilityResponse(IoCapability::NO_INPUT_NO_OUTPUT);
  pairing_delegate.SetConfirmPairingCallback([this](PeerId peer_id, auto cb) {
    EXPECT_EQ(peer()->identifier(), peer_id);
    ASSERT_TRUE(cb);
    cb(false);
  });
  bool confirmed = true;
  pairing_state.OnUserConfirmationRequest(
      kTestPasskey, [&confirmed](bool confirm) { confirmed = confirm; });

  EXPECT_FALSE(confirmed);

  pairing_delegate.SetCompletePairingCallback(
      [this](PeerId peer_id, sm::Result<> status) {
        EXPECT_EQ(peer()->identifier(), peer_id);
        EXPECT_TRUE(status.is_error());
      });

  // The controller sends a SimplePairingComplete indicating the failure after
  // we send a Negative Confirmation.
  const auto status_code =
      pw::bluetooth::emboss::StatusCode::AUTHENTICATION_FAILURE;
  pairing_state.OnSimplePairingComplete(status_code);

  // The bonding key should not have been touched.
  EXPECT_EQ(existing_link_key, peer()->bredr()->link_key());

  EXPECT_EQ(1, status_handler.call_count());
  ASSERT_TRUE(status_handler.status().has_value());
  EXPECT_EQ(ToResult(status_code), status_handler.status().value());
}

TEST_F(PairingStateTest, ResponderSignalsCompletionOfPairing) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  EXPECT_FALSE(pairing_state.initiator());

  auto existing_link_key = sm::LTK(
      sm::SecurityProperties(kTestUnauthenticatedLinkKeyType192), kTestLinkKey);

  peer()->MutBrEdr().SetBondData(existing_link_key);
  EXPECT_FALSE(connection()->ltk().has_value());

  auto reply_key = pairing_state.OnLinkKeyRequest();
  ASSERT_TRUE(reply_key.has_value());
  EXPECT_EQ(kTestLinkKey, reply_key.value());
  EXPECT_EQ(0, status_handler.call_count());

  // If a pairing request comes in after the peer has already asked for the key,
  // we add it's completion to the queue.
  TestStatusHandler new_pairing_handler;
  pairing_state.InitiatePairing(kNoSecurityRequirements,
                                new_pairing_handler.MakeStatusCallback());

  connection()->TriggerEncryptionChangeCallback(fit::ok(true));

  auto expected_status = pw::bluetooth::emboss::StatusCode::SUCCESS;
  EXPECT_EQ(1, status_handler.call_count());
  ASSERT_TRUE(status_handler.status().has_value());
  EXPECT_EQ(ToResult(expected_status), status_handler.status().value());

  // and the new pairing handler gets called back too
  EXPECT_EQ(1, new_pairing_handler.call_count());
  ASSERT_TRUE(new_pairing_handler.status().has_value());
  EXPECT_EQ(ToResult(expected_status), new_pairing_handler.status().value());

  // The link key should be stored in the connection now.
  EXPECT_EQ(kTestLinkKey, connection()->ltk());
}

TEST_F(
    PairingStateTest,
    AuthenticationCompleteWithMissingKeyRetriesWithoutKeyAndDoesntAutoConfirmAccepted) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/true,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  FakePairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  auto existing_link_key = sm::LTK(
      sm::SecurityProperties(kTestUnauthenticatedLinkKeyType192), kTestLinkKey);

  peer()->MutBrEdr().SetBondData(existing_link_key);
  EXPECT_FALSE(connection()->ltk().has_value());

  pairing_state.InitiatePairing(kNoSecurityRequirements, NoOpStatusCallback);
  EXPECT_EQ(1u, auth_request_count());

  auto reply_key = pairing_state.OnLinkKeyRequest();
  ASSERT_TRUE(reply_key.has_value());
  EXPECT_EQ(kTestLinkKey, reply_key.value());
  EXPECT_EQ(0, status_handler.call_count());

  // Peer says that they don't have a key.
  pairing_state.OnAuthenticationComplete(
      pw::bluetooth::emboss::StatusCode::PIN_OR_KEY_MISSING);
  ASSERT_EQ(0, status_handler.call_count());
  // We should retry the authentication request, this time pretending we don't
  // have a key.
  EXPECT_EQ(2u, auth_request_count());

  EXPECT_EQ(std::nullopt, pairing_state.OnLinkKeyRequest());
  EXPECT_EQ(0, status_handler.call_count());

  static_cast<void>(pairing_state.OnIoCapabilityRequest());
  pairing_state.OnIoCapabilityResponse(IoCapability::NO_INPUT_NO_OUTPUT);
  pairing_delegate.SetConfirmPairingCallback([this](PeerId peer_id, auto cb) {
    EXPECT_EQ(peer()->identifier(), peer_id);
    ASSERT_TRUE(cb);
    cb(true);
  });
  bool confirmed = false;
  pairing_state.OnUserConfirmationRequest(
      kTestPasskey, [&confirmed](bool confirm) { confirmed = confirm; });

  EXPECT_TRUE(confirmed);

  pairing_delegate.SetCompletePairingCallback(
      [this](PeerId peer_id, sm::Result<> status) {
        EXPECT_EQ(peer()->identifier(), peer_id);
        EXPECT_EQ(fit::ok(), status);
      });

  // The controller sends a SimplePairingComplete indicating the success, then
  // the controller sends us the new link key, and Authentication Complete.
  // Negative Confirmation.
  auto status_code = pw::bluetooth::emboss::StatusCode::SUCCESS;
  pairing_state.OnSimplePairingComplete(status_code);

  const auto new_link_key_value = UInt128{0xC0,
                                          0xDE,
                                          0xFA,
                                          0xCE,
                                          0x00,
                                          0x00,
                                          0x00,
                                          0x00,
                                          0x00,
                                          0x00,
                                          0x00,
                                          0x00,
                                          0x00,
                                          0x00,
                                          0x00,
                                          0x04};

  pairing_state.OnLinkKeyNotification(new_link_key_value,
                                      kTestUnauthenticatedLinkKeyType192);
  pairing_state.OnAuthenticationComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  // then we request encryption, which when it finishes, completes pairing.
  ASSERT_EQ(1, connection()->start_encryption_count());
  connection()->TriggerEncryptionChangeCallback(fit::ok(true));

  EXPECT_EQ(1, status_handler.call_count());
  ASSERT_TRUE(status_handler.status().has_value());
  EXPECT_EQ(ToResult(status_code), status_handler.status().value());

  // The new link key should be stored in the connection now.
  auto new_link_key = hci_spec::LinkKey(new_link_key_value, 0, 0);
  EXPECT_EQ(new_link_key, connection()->ltk());
}

TEST_F(
    PairingStateTest,
    MultipleQueuedPairingRequestsWithSameSecurityRequirementsCompleteAtSameTimeWithSuccess) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  TestStatusHandler initiate_status_handler_0;
  pairing_state.InitiatePairing(kNoSecurityRequirements,
                                initiate_status_handler_0.MakeStatusCallback());
  EXPECT_EQ(1u, auth_request_count());

  TestStatusHandler initiate_status_handler_1;
  pairing_state.InitiatePairing(kNoSecurityRequirements,
                                initiate_status_handler_1.MakeStatusCallback());
  EXPECT_EQ(1u, auth_request_count());

  AdvanceToEncryptionAsInitiator(&pairing_state);
  EXPECT_EQ(0, status_handler.call_count());
  EXPECT_EQ(1, connection()->start_encryption_count());

  connection()->TriggerEncryptionChangeCallback(fit::ok(true));
  EXPECT_EQ(1, status_handler.call_count());
  ASSERT_TRUE(status_handler.status());
  EXPECT_EQ(fit::ok(), *status_handler.status());
  ASSERT_EQ(1, initiate_status_handler_0.call_count());
  EXPECT_EQ(fit::ok(), *initiate_status_handler_0.status());
  ASSERT_EQ(1, initiate_status_handler_1.call_count());
  EXPECT_EQ(fit::ok(), *initiate_status_handler_1.status());
}

TEST_F(
    PairingStateTest,
    MultipleQueuedPairingRequestsWithAuthSecurityRequirementsCompleteAtSameTimeWithInsufficientSecurityFailure) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate.GetWeakPtr());

  constexpr BrEdrSecurityRequirements kSecurityRequirements{
      .authentication = true, .secure_connections = false};

  TestStatusHandler initiate_status_handler_0;
  pairing_state.InitiatePairing(kSecurityRequirements,
                                initiate_status_handler_0.MakeStatusCallback());
  EXPECT_EQ(1u, auth_request_count());

  TestStatusHandler initiate_status_handler_1;
  pairing_state.InitiatePairing(kSecurityRequirements,
                                initiate_status_handler_1.MakeStatusCallback());
  EXPECT_EQ(1u, auth_request_count());

  // Pair with unauthenticated link key.
  AdvanceToEncryptionAsInitiator(&pairing_state);
  EXPECT_EQ(0, status_handler.call_count());
  EXPECT_EQ(1, connection()->start_encryption_count());

  connection()->TriggerEncryptionChangeCallback(fit::ok(true));
  EXPECT_EQ(1, status_handler.call_count());
  ASSERT_TRUE(status_handler.status());
  EXPECT_EQ(fit::ok(), *status_handler.status());
  ASSERT_EQ(1, initiate_status_handler_0.call_count());
  EXPECT_EQ(ToResult(HostError::kInsufficientSecurity),
            initiate_status_handler_0.status().value());
  ASSERT_EQ(1, initiate_status_handler_1.call_count());
  EXPECT_EQ(ToResult(HostError::kInsufficientSecurity),
            initiate_status_handler_1.status().value());
}

TEST_F(
    PairingStateTest,
    AuthPairingRequestDuringInitiatorNoAuthPairingFailsQueuedAuthPairingRequest) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  NoOpPairingDelegate pairing_delegate_no_io(
      sm::IOCapability::kNoInputNoOutput);
  pairing_state.SetPairingDelegate(pairing_delegate_no_io.GetWeakPtr());

  TestStatusHandler initiate_status_handler_0;
  pairing_state.InitiatePairing(kNoSecurityRequirements,
                                initiate_status_handler_0.MakeStatusCallback());

  TestStatusHandler initiate_status_handler_1;
  constexpr BrEdrSecurityRequirements kSecurityRequirements{
      .authentication = true, .secure_connections = false};
  pairing_state.InitiatePairing(kSecurityRequirements,
                                initiate_status_handler_1.MakeStatusCallback());

  // Pair with unauthenticated link key.
  AdvanceToEncryptionAsInitiator(&pairing_state);

  EXPECT_EQ(0, status_handler.call_count());
  EXPECT_EQ(1, connection()->start_encryption_count());

  FakePairingDelegate fake_pairing_delegate(sm::IOCapability::kDisplayYesNo);
  pairing_state.SetPairingDelegate(fake_pairing_delegate.GetWeakPtr());

  connection()->TriggerEncryptionChangeCallback(fit::ok(true));
  EXPECT_EQ(1, status_handler.call_count());
  ASSERT_TRUE(status_handler.status());
  EXPECT_EQ(fit::ok(), *status_handler.status());
  ASSERT_EQ(1, initiate_status_handler_0.call_count());
  EXPECT_EQ(fit::ok(), *initiate_status_handler_0.status());
  ASSERT_EQ(1, initiate_status_handler_1.call_count());
  EXPECT_EQ(ToResult(HostError::kInsufficientSecurity),
            initiate_status_handler_1.status().value());

  // Pairing for second request should not start.
  EXPECT_FALSE(pairing_state.initiator());
}

TEST_F(
    PairingStateTest,
    InitiatingPairingDuringAuthenticationWithExistingUnauthenticatedLinkKey) {
  TestStatusHandler status_handler;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());
  FakePairingDelegate fake_pairing_delegate(sm::IOCapability::kDisplayYesNo);
  pairing_state.SetPairingDelegate(fake_pairing_delegate.GetWeakPtr());

  peer()->MutBrEdr().SetBondData(
      sm::LTK(sm::SecurityProperties(kTestUnauthenticatedLinkKeyType192),
              kTestLinkKey));

  TestStatusHandler initiator_status_handler_0;
  pairing_state.InitiatePairing(
      kNoSecurityRequirements, initiator_status_handler_0.MakeStatusCallback());
  EXPECT_EQ(1u, auth_request_count());

  TestStatusHandler initiator_status_handler_1;
  constexpr BrEdrSecurityRequirements kSecurityRequirements{
      .authentication = true, .secure_connections = false};
  pairing_state.InitiatePairing(
      kSecurityRequirements, initiator_status_handler_1.MakeStatusCallback());
  EXPECT_EQ(1u, auth_request_count());

  // Authenticate with link key.
  EXPECT_NE(std::nullopt, pairing_state.OnLinkKeyRequest());
  EXPECT_TRUE(connection()->ltk().has_value());
  pairing_state.OnAuthenticationComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);

  EXPECT_EQ(0, status_handler.call_count());
  EXPECT_EQ(1, connection()->start_encryption_count());

  connection()->TriggerEncryptionChangeCallback(fit::ok(true));
  ASSERT_EQ(1, status_handler.call_count());
  EXPECT_EQ(fit::ok(), *status_handler.status());
  ASSERT_EQ(1, initiator_status_handler_0.call_count());
  EXPECT_EQ(fit::ok(), *initiator_status_handler_0.status());
  EXPECT_EQ(0, initiator_status_handler_1.call_count());

  fake_pairing_delegate.SetDisplayPasskeyCallback(
      [](PeerId peer_id,
         uint32_t value,
         PairingDelegate::DisplayMethod method,
         auto cb) { cb(true); });
  fake_pairing_delegate.SetCompletePairingCallback(
      [](PeerId peer_id, sm::Result<> status) {
        EXPECT_EQ(fit::ok(), status);
      });

  // Pairing for second request should start.
  EXPECT_EQ(2u, auth_request_count());
  EXPECT_TRUE(pairing_state.initiator());
  EXPECT_EQ(std::nullopt, pairing_state.OnLinkKeyRequest());
  EXPECT_EQ(IoCapability::DISPLAY_YES_NO,
            *pairing_state.OnIoCapabilityRequest());
  pairing_state.OnIoCapabilityResponse(IoCapability::DISPLAY_YES_NO);

  bool confirmed = false;
  pairing_state.OnUserConfirmationRequest(
      kTestPasskey, [&confirmed](bool confirm) { confirmed = confirm; });
  EXPECT_TRUE(confirmed);

  pairing_state.OnSimplePairingComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  pairing_state.OnLinkKeyNotification(kTestLinkKeyValue,
                                      kTestAuthenticatedLinkKeyType192);
  pairing_state.OnAuthenticationComplete(
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  EXPECT_EQ(2, connection()->start_encryption_count());

  connection()->TriggerEncryptionChangeCallback(fit::ok(true));
  ASSERT_EQ(2, status_handler.call_count());
  EXPECT_EQ(fit::ok(), *status_handler.status());
  EXPECT_EQ(1, initiator_status_handler_0.call_count());
  ASSERT_EQ(1, initiator_status_handler_1.call_count());
  EXPECT_EQ(fit::ok(), *initiator_status_handler_1.status());

  // No further pairing should occur.
  EXPECT_EQ(2u, auth_request_count());
  EXPECT_FALSE(pairing_state.initiator());
}

#ifndef NINSPECT
TEST_F(PairingStateTest, Inspect) {
  TestStatusHandler status_handler;

  inspect::Inspector inspector;

  PairingState pairing_state(peer()->GetWeakPtr(),
                             connection(),
                             /*link_initiated=*/false,
                             MakeAuthRequestCallback(),
                             status_handler.MakeStatusCallback());

  pairing_state.AttachInspect(inspector.GetRoot(), "pairing_state");

  auto security_properties_matcher = AllOf(NodeMatches(AllOf(
      NameMatches("security_properties"),
      PropertyList(UnorderedElementsAre(StringIs("level", "not secure"),
                                        BoolIs("encrypted", false),
                                        BoolIs("secure_connections", false),
                                        BoolIs("authenticated", false))))));

  auto pairing_state_matcher =
      AllOf(NodeMatches(AllOf(NameMatches("pairing_state"),
                              PropertyList(UnorderedElementsAre(
                                  StringIs("encryption_status", "OFF"))))),
            ChildrenMatch(UnorderedElementsAre(security_properties_matcher)));

  inspect::Hierarchy hierarchy = bt::testing::ReadInspect(inspector);
  EXPECT_THAT(hierarchy, ChildrenMatch(ElementsAre(pairing_state_matcher)));
}
#endif  // NINSPECT

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