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

#include "src/connectivity/bluetooth/core/bt-host/hci/connection.h"

#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/hci.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/l2cap_defs.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/controller_test.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/mock_controller.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/test_packets.h"

namespace bt::hci {
namespace {

constexpr ConnectionHandle kTestHandle = 0x0001;
const LEConnectionParameters kTestParams(1, 1, 1);
const DeviceAddress kLEAddress1(DeviceAddress::Type::kLEPublic, {1});
const DeviceAddress kLEAddress2(DeviceAddress::Type::kLEPublic, {2});
const DeviceAddress kACLAddress1(DeviceAddress::Type::kBREDR, {3});
const DeviceAddress kACLAddress2(DeviceAddress::Type::kBREDR, {4});

constexpr UInt128 kLTK{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}};
constexpr uint64_t kRand = 1;
constexpr uint16_t kEDiv = 255;
constexpr LinkKeyType kLinkKeyType = LinkKeyType::kAuthenticatedCombination256;

const DataBufferInfo kBrEdrBufferInfo(1024, 5);
const DataBufferInfo kLeBufferInfo(1024, 1);

using bt::testing::CommandTransaction;

using TestingBase = bt::testing::ControllerTest<bt::testing::MockController>;

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

 protected:
  void SetUp() override {
    TestingBase::SetUp();
    InitializeACLDataChannel(kBrEdrBufferInfo, kLeBufferInfo);
    StartTestDevice();
  }

  ConnectionPtr NewLEConnection(Connection::Role role = Connection::Role::kMaster,
                                ConnectionHandle handle = kTestHandle) {
    return Connection::CreateLE(handle, role, kLEAddress1, kLEAddress2, kTestParams,
                                transport()->WeakPtr());
  }

  ConnectionPtr NewACLConnection(Connection::Role role = Connection::Role::kMaster,
                                 ConnectionHandle handle = kTestHandle) {
    return Connection::CreateACL(handle, role, kACLAddress1, kACLAddress2, transport()->WeakPtr());
  }
};

// Tests using this harness will be instantiated using ACL and LE link types.
// See INSTANTIATE_TEST_SUITE_P(HCI_ConnectionTest, LinkTypeConnectionTest, ...)
class LinkTypeConnectionTest : public ConnectionTest,
                               public ::testing::WithParamInterface<Connection::LinkType> {
 protected:
  ConnectionPtr NewConnection(Connection::Role role = Connection::Role::kMaster,
                              ConnectionHandle handle = kTestHandle) {
    const Connection::LinkType ll_type = GetParam();
    switch (ll_type) {
      case Connection::LinkType::kACL:
        return NewACLConnection(role, handle);
      case Connection::LinkType::kLE:
        return NewLEConnection(role, handle);
      default:
        break;
    }
    ZX_PANIC("Invalid link type: %u", static_cast<unsigned>(ll_type));
    return nullptr;
  }

  // Assigns the appropriate test link key based on the type of link being tested.
  void SetTestLinkKey(Connection* connection) {
    const Connection::LinkType ll_type = GetParam();
    if (ll_type == Connection::LinkType::kLE) {
      connection->set_le_ltk(LinkKey(kLTK, kRand, kEDiv));
    } else {
      connection->set_bredr_link_key(LinkKey(kLTK, 0, 0), kLinkKeyType);
    }
  }
};

using HCI_ConnectionTest = ConnectionTest;

TEST_F(HCI_ConnectionTest, Getters) {
  auto connection = NewLEConnection();

  EXPECT_EQ(Connection::LinkType::kLE, connection->ll_type());
  EXPECT_EQ(kTestHandle, connection->handle());
  EXPECT_EQ(Connection::Role::kMaster, connection->role());
  EXPECT_EQ(kTestParams, connection->low_energy_parameters());
  EXPECT_EQ(kLEAddress1, connection->local_address());
  EXPECT_EQ(kLEAddress2, connection->peer_address());

  EXPECT_EQ(std::nullopt, connection->ltk());
  connection->set_le_ltk(LinkKey());
  ASSERT_TRUE(connection->ltk().has_value());
  EXPECT_EQ(LinkKey(), connection->ltk().value());

  EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kTestHandle));
}

TEST_F(HCI_ConnectionTest, AclLinkKeyAndTypeAccessors) {
  auto connection = NewACLConnection();

  EXPECT_EQ(Connection::LinkType::kACL, connection->ll_type());
  EXPECT_EQ(std::nullopt, connection->ltk());
  EXPECT_EQ(std::nullopt, connection->ltk_type());
  connection->set_bredr_link_key(LinkKey(), kLinkKeyType);
  ASSERT_TRUE(connection->ltk().has_value());
  EXPECT_EQ(LinkKey(), connection->ltk().value());
  ASSERT_TRUE(connection->ltk_type().has_value());
  EXPECT_EQ(kLinkKeyType, connection->ltk_type().value());

  EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kTestHandle));
}

TEST_P(LinkTypeConnectionTest, Disconnect) {
  // clang-format off

  // HCI_Disconnect (handle: 0x0001, reason: RemoteUserTerminatedConnection)
  auto req_bytes = CreateStaticByteBuffer(
      0x06, 0x04, 0x03, 0x01, 0x00, StatusCode::kRemoteUserTerminatedConnection);

  // Respond with Command Status and Disconnection Complete.
  auto cmd_status_bytes = CreateStaticByteBuffer(
      kCommandStatusEventCode, 0x04, StatusCode::kSuccess, 1, 0x06, 0x04);

  auto disc_cmpl_bytes = CreateStaticByteBuffer(
      kDisconnectionCompleteEventCode, 0x04,
      StatusCode::kSuccess, 0x01, 0x00, StatusCode::kConnectionTerminatedByLocalHost);

  // clang-format on

  EXPECT_CMD_PACKET_OUT(test_device(), req_bytes, &cmd_status_bytes, &disc_cmpl_bytes);

  bool callback_called = false;
  test_device()->SetTransactionCallback([&callback_called] { callback_called = true; },
                                        dispatcher());

  auto connection = NewConnection();

  size_t disconn_cb_count = 0;
  auto disconn_complete_cb = [&](const Connection* cb_conn, auto reason) {
    disconn_cb_count++;
    EXPECT_EQ(reason, StatusCode::kConnectionTerminatedByLocalHost);
  };
  connection->set_peer_disconnect_callback(disconn_complete_cb);

  connection->Disconnect(StatusCode::kRemoteUserTerminatedConnection);

  RunLoopUntilIdle();
  EXPECT_TRUE(callback_called);
  EXPECT_EQ(1u, disconn_cb_count);
}

TEST_P(LinkTypeConnectionTest, LinkRegistrationAndLocalDisconnection) {
  const Connection::LinkType ll_type = GetParam();
  const ConnectionHandle kHandle0 = 0x0001;
  const ConnectionHandle kHandle1 = 0x0002;

  const auto& kBufferInfo =
      ll_type == Connection::LinkType::kACL ? kBrEdrBufferInfo : kLeBufferInfo;

  // Should register connection with ACL Data Channel.
  auto conn0 = NewConnection(Connection::Role::kMaster, kHandle0);
  auto conn1 = NewConnection(Connection::Role::kMaster, kHandle1);

  size_t handle0_packet_count = 0;
  size_t handle1_packet_count = 0;
  auto data_callback = [&](const ByteBuffer& bytes) {
    PacketView<hci::ACLDataHeader> packet(&bytes, bytes.size() - sizeof(ACLDataHeader));
    ConnectionHandle connection_handle = le16toh(packet.header().handle_and_flags) & 0xFFF;

    if (connection_handle == kHandle0) {
      handle0_packet_count++;
    } else {
      ASSERT_EQ(kHandle1, connection_handle);
      handle1_packet_count++;
    }
  };
  test_device()->SetDataCallback(data_callback, dispatcher());

  // Fill controller buffer.
  for (size_t i = 0; i < kBufferInfo.max_num_packets(); i++) {
    // Connection handle should have been registered with ACL Data Channel.
    EXPECT_TRUE(acl_data_channel()->SendPacket(
        ACLDataPacket::New(kHandle0, ACLPacketBoundaryFlag::kFirstNonFlushable,
                           ACLBroadcastFlag::kPointToPoint, 1),
        l2cap::kInvalidChannelId, AclDataChannel::PacketPriority::kLow));
  }

  EXPECT_TRUE(acl_data_channel()->SendPacket(
      ACLDataPacket::New(kHandle1, ACLPacketBoundaryFlag::kFirstNonFlushable,
                         ACLBroadcastFlag::kPointToPoint, 1),
      l2cap::kInvalidChannelId, AclDataChannel::PacketPriority::kLow));

  RunLoopUntilIdle();

  EXPECT_EQ(handle0_packet_count, kBufferInfo.max_num_packets());
  EXPECT_EQ(handle1_packet_count, 0u);

  const auto disconnect_status_rsp = testing::DisconnectStatusResponsePacket();
  EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kHandle0), &disconnect_status_rsp);

  conn0->Disconnect(StatusCode::kRemoteUserTerminatedConnection);
  RunLoopUntilIdle();

  // controller packet counts for |kHandle0| should not have been cleared after disconnect.
  EXPECT_EQ(handle1_packet_count, 0u);

  // Disconnection Complete handler should clear controller packet counts, so packet for |kHandle1|
  // should be sent.
  DynamicByteBuffer disconnection_complete(testing::DisconnectionCompletePacket(kHandle0));
  test_device()->SendCommandChannelPacket(disconnection_complete);
  RunLoopUntilIdle();

  EXPECT_EQ(handle1_packet_count, 1u);

  // Connection handle should have been unregistered with ACL Data Channel.
  EXPECT_FALSE(acl_data_channel()->SendPacket(
      ACLDataPacket::New(kHandle0, ACLPacketBoundaryFlag::kFirstNonFlushable,
                         ACLBroadcastFlag::kPointToPoint, 1),
      l2cap::kInvalidChannelId, AclDataChannel::PacketPriority::kLow));

  EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kHandle1));
}

// In remote disconnection, Connection::Disconnect is not called. Instead,
// Connection::OnDisconnectionComplete is invoked and handles all cleanup.
TEST_P(LinkTypeConnectionTest, LinkRegistrationAndRemoteDisconnection) {
  const Connection::LinkType ll_type = GetParam();
  const ConnectionHandle kHandle0 = 0x0001;
  const ConnectionHandle kHandle1 = 0x0002;

  const auto& kBufferInfo =
      ll_type == Connection::LinkType::kACL ? kBrEdrBufferInfo : kLeBufferInfo;

  // Should register connection with ACL Data Channel.
  auto conn0 = NewConnection(Connection::Role::kMaster, kHandle0);

  auto conn1 = NewConnection(Connection::Role::kMaster, kHandle1);

  size_t handle0_packet_count = 0;
  size_t handle1_packet_count = 0;
  auto data_callback = [&](const ByteBuffer& bytes) {
    PacketView<hci::ACLDataHeader> packet(&bytes, bytes.size() - sizeof(ACLDataHeader));
    ConnectionHandle connection_handle = le16toh(packet.header().handle_and_flags) & 0xFFF;

    if (connection_handle == kHandle0) {
      handle0_packet_count++;
    } else {
      ASSERT_EQ(kHandle1, connection_handle);
      handle1_packet_count++;
    }
  };
  test_device()->SetDataCallback(data_callback, dispatcher());

  // Fill controller buffer.
  for (size_t i = 0; i < kBufferInfo.max_num_packets(); i++) {
    // Connection handle should have been registered with ACL Data Channel.
    EXPECT_TRUE(acl_data_channel()->SendPacket(
        ACLDataPacket::New(kHandle0, ACLPacketBoundaryFlag::kFirstNonFlushable,
                           ACLBroadcastFlag::kPointToPoint, 1),
        l2cap::kInvalidChannelId, AclDataChannel::PacketPriority::kLow));
  }

  EXPECT_TRUE(acl_data_channel()->SendPacket(
      ACLDataPacket::New(kHandle1, ACLPacketBoundaryFlag::kFirstNonFlushable,
                         ACLBroadcastFlag::kPointToPoint, 1),
      l2cap::kInvalidChannelId, AclDataChannel::PacketPriority::kLow));

  RunLoopUntilIdle();

  EXPECT_EQ(handle0_packet_count, kBufferInfo.max_num_packets());
  EXPECT_EQ(handle1_packet_count, 0u);

  size_t disconn_cb_count = 0;
  auto disconn_complete_cb = [&](const Connection* cb_conn, auto /*reason*/) {
    ASSERT_TRUE(cb_conn);
    EXPECT_EQ(kHandle0, cb_conn->handle());
    disconn_cb_count++;
  };
  conn0->set_peer_disconnect_callback(disconn_complete_cb);

  // Disconnection Complete handler should clear controller packet counts, so packet for |kHandle1|
  // should be sent.
  DynamicByteBuffer disconnection_complete(testing::DisconnectionCompletePacket(kHandle0));
  test_device()->SendCommandChannelPacket(disconnection_complete);
  RunLoopUntilIdle();

  EXPECT_EQ(1u, disconn_cb_count);

  // Connection handle should have been unregistered with ACL Data Channel.
  EXPECT_FALSE(acl_data_channel()->SendPacket(
      ACLDataPacket::New(kHandle0, ACLPacketBoundaryFlag::kFirstNonFlushable,
                         ACLBroadcastFlag::kPointToPoint, 1),
      l2cap::kInvalidChannelId, AclDataChannel::PacketPriority::kLow));

  // Since controller packet count was cleared, packet for |kHandle1| should
  // have been sent.
  EXPECT_EQ(handle1_packet_count, 1u);

  EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kHandle1));
}

TEST_F(HCI_ConnectionTest, StartEncryptionFailsAsLowEnergySlave) {
  auto conn = NewLEConnection(Connection::Role::kSlave);
  conn->set_le_ltk(LinkKey());
  EXPECT_FALSE(conn->StartEncryption());
  EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kTestHandle));
}

TEST_F(HCI_ConnectionTest, StartEncryptionSucceedsAsLowEnergyMaster) {
  auto conn = NewLEConnection(Connection::Role::kMaster);
  auto ltk = LinkKey();
  conn->set_le_ltk(ltk);
  EXPECT_TRUE(conn->StartEncryption());
  EXPECT_CMD_PACKET_OUT(test_device(), testing::LEStartEncryptionPacket(kTestHandle, ltk.rand(),
                                                                        ltk.ediv(), ltk.value()));
}

TEST_F(HCI_ConnectionTest, StartEncryptionSucceedsWithBrEdrLinkKeyType) {
  auto conn = NewACLConnection();
  conn->set_bredr_link_key(LinkKey(), kLinkKeyType);
  EXPECT_TRUE(conn->StartEncryption());
  EXPECT_CMD_PACKET_OUT(test_device(),
                        testing::SetConnectionEncryption(kTestHandle, /*enable=*/true));
}

TEST_P(LinkTypeConnectionTest, DisconnectError) {
  // clang-format off

  // HCI_Disconnect (handle: 0x0001, reason: RemoteUserTerminatedConnection)
  auto req_bytes = CreateStaticByteBuffer(
      0x06, 0x04, 0x03, 0x01, 0x00, StatusCode::kRemoteUserTerminatedConnection);

  // Respond with Command Status and Disconnection Complete.
  auto cmd_status_bytes = CreateStaticByteBuffer(
      kCommandStatusEventCode, 0x04, StatusCode::kSuccess, 1, 0x06, 0x04);

  auto disc_cmpl_bytes = CreateStaticByteBuffer(
      kDisconnectionCompleteEventCode, 0x04,
      StatusCode::kCommandDisallowed, 0x01, 0x00, StatusCode::kConnectionTerminatedByLocalHost);

  // clang-format on

  EXPECT_CMD_PACKET_OUT(test_device(), req_bytes, &cmd_status_bytes, &disc_cmpl_bytes);

  // The callback should get called regardless of the procedure status.
  bool callback_called = false;
  test_device()->SetTransactionCallback([&callback_called] { callback_called = true; },
                                        dispatcher());

  auto connection = NewConnection();

  connection->Disconnect(StatusCode::kRemoteUserTerminatedConnection);

  RunLoopUntilIdle();
  EXPECT_TRUE(callback_called);
}

TEST_P(LinkTypeConnectionTest, StartEncryptionNoLinkKey) {
  auto conn = NewConnection();
  EXPECT_FALSE(conn->StartEncryption());
  EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kTestHandle));
}

// HCI Command Status event is received with an error status.
TEST_F(HCI_ConnectionTest, LEStartEncryptionFailsAtStatus) {
  // clang-format off
  auto kExpectedCommand = CreateStaticByteBuffer(
    0x19, 0x20,  // HCI_LE_Start_Encryption
    28,          // parameter total size
    0x01, 0x00,  // connection handle: 1
    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // rand: 1
    0xFF, 0x00,  // ediv: 255
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16  // LTK
  );
  auto kErrorStatus = CreateStaticByteBuffer(
    0x0F,       // HCI Command Status event code
    4,          // parameter total size
    0x0C,       // "Command Disallowed" error
    1,          // num_hci_command_packets
    0x19, 0x20  // opcode: HCI_LE_Start_Encryption
  );
  // clang-format on

  EXPECT_CMD_PACKET_OUT(test_device(), kExpectedCommand, &kErrorStatus);

  bool callback = false;
  auto conn = NewLEConnection();
  conn->set_le_ltk(LinkKey(kLTK, kRand, kEDiv));
  conn->set_encryption_change_callback([&](Status status, bool enabled) {
    EXPECT_FALSE(status);
    EXPECT_FALSE(enabled);
    EXPECT_EQ(StatusCode::kCommandDisallowed, status.protocol_error());
    callback = true;
  });

  EXPECT_TRUE(conn->StartEncryption());

  RunLoopUntilIdle();
  EXPECT_TRUE(callback);
  EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kTestHandle));
}

TEST_F(HCI_ConnectionTest, LEStartEncryptionSendsSetLeConnectionEncryptionCommand) {
  auto kExpectedCommand =
      CreateStaticByteBuffer(0x19, 0x20,  // HCI_LE_Start_Encryption
                             28,          // parameter total size
                             0x01, 0x00,  // connection handle: 1
                             0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,        // rand: 1
                             0xFF, 0x00,                                            // ediv: 255
                             1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16  // LTK
      );
  auto kStatus = CreateStaticByteBuffer(0x0F,       // HCI Command Status event code
                                        4,          // parameter total size
                                        0x00,       // success status
                                        1,          // num_hci_command_packets
                                        0x19, 0x20  // opcode: HCI_LE_Start_Encryption
  );

  EXPECT_CMD_PACKET_OUT(test_device(), kExpectedCommand, &kStatus);

  bool callback = false;
  auto conn = NewLEConnection();
  conn->set_le_ltk(LinkKey(kLTK, kRand, kEDiv));
  conn->set_encryption_change_callback([&](Status status, bool enabled) { callback = true; });

  EXPECT_TRUE(conn->StartEncryption());

  // Callback shouldn't be called until the controller sends an encryption
  // changed event.
  RunLoopUntilIdle();
  EXPECT_FALSE(callback);
  EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kTestHandle));
}

// HCI Command Status event is received with an error status.
TEST_F(HCI_ConnectionTest, AclStartEncryptionFailsAtStatus) {
  auto kExpectedCommand = CreateStaticByteBuffer(0x13, 0x04,  // HCI_Set_Connection_Encryption
                                                 3,           // parameter total size
                                                 0x01, 0x00,  // connection handle
                                                 0x01         // encryption enable
  );
  auto kErrorStatus = CreateStaticByteBuffer(0x0F,       // HCI Command Status event code
                                             4,          // parameter total size
                                             0x0C,       // "Command Disallowed" error
                                             1,          // num_hci_command_packets
                                             0x13, 0x04  // opcode: HCI_Set_Connection_Encryption
  );

  EXPECT_CMD_PACKET_OUT(test_device(), kExpectedCommand, &kErrorStatus);

  bool callback = false;
  auto conn = NewACLConnection();
  conn->set_bredr_link_key(LinkKey(kLTK, 0, 0), kLinkKeyType);
  conn->set_encryption_change_callback([&](Status status, bool enabled) {
    EXPECT_FALSE(status);
    EXPECT_FALSE(enabled);
    EXPECT_EQ(StatusCode::kCommandDisallowed, status.protocol_error());
    callback = true;
  });

  EXPECT_TRUE(conn->StartEncryption());

  RunLoopUntilIdle();
  EXPECT_TRUE(callback);
  EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kTestHandle));
}

TEST_F(HCI_ConnectionTest, AclStartEncryptionSendsSetConnectionEncryptionCommand) {
  auto kExpectedCommand = CreateStaticByteBuffer(0x13, 0x04,  // HCI_Set_Connection_Encryption
                                                 3,           // parameter total size
                                                 0x01, 0x00,  // connection handle
                                                 0x01         // encryption enable
  );
  auto kStatus = CreateStaticByteBuffer(0x0F,       // HCI Command Status event code
                                        4,          // parameter total size
                                        0x00,       // success status
                                        1,          // num_hci_command_packets
                                        0x13, 0x04  // opcode: HCI_Set_Connection_Encryption
  );

  EXPECT_CMD_PACKET_OUT(test_device(), kExpectedCommand, &kStatus);

  bool callback = false;
  auto conn = NewACLConnection();
  conn->set_bredr_link_key(LinkKey(kLTK, 0, 0), kLinkKeyType);
  conn->set_encryption_change_callback([&](Status status, bool enabled) { callback = true; });

  EXPECT_TRUE(conn->StartEncryption());

  // Callback shouldn't be called until the controller sends an encryption changed event.
  RunLoopUntilIdle();
  EXPECT_FALSE(callback);
  EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kTestHandle));
}

TEST_P(LinkTypeConnectionTest, EncryptionChangeIgnoredEvents) {
  // clang-format off
  auto kEncChangeMalformed = CreateStaticByteBuffer(
    0x08,       // HCI Encryption Change event code
    3,          // parameter total size
    0x00,       // status
    0x01, 0x00  // connection handle: 1
    // Last byte missing
  );
  auto kEncChangeWrongHandle = CreateStaticByteBuffer(
    0x08,        // HCI Encryption Change event code
    4,           // parameter total size
    0x00,        // status
    0x02, 0x00,  // connection handle: 2
    0x01         // encryption enabled
  );
  // clang-format on

  bool callback = false;
  auto conn = NewConnection();
  SetTestLinkKey(conn.get());
  conn->set_encryption_change_callback([&](Status, bool) { callback = true; });

  test_device()->SendCommandChannelPacket(kEncChangeMalformed);
  test_device()->SendCommandChannelPacket(kEncChangeWrongHandle);

  RunLoopUntilIdle();
  EXPECT_FALSE(callback);
  EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kTestHandle));
}

const auto kEncryptionChangeEventEnabled =
    CreateStaticByteBuffer(0x08,        // HCI Encryption Change event code
                           4,           // parameter total size
                           0x00,        // status
                           0x01, 0x00,  // connection handle: 1
                           0x01         // encryption enabled
    );

const auto kReadEncryptionKeySizeCommand =
    CreateStaticByteBuffer(0x08, 0x14,  // opcode: HCI_ReadEncryptionKeySize
                           0x02,        // parameter size
                           0x01, 0x00   // connection handle: 0x0001
    );

const auto kDisconnectCommand = CreateStaticByteBuffer(0x06, 0x04,  // opcode: HCI_Disconnect
                                                       0x03,        // parameter total size
                                                       0x01, 0x00,  // handle: 1
                                                       0x05  // reason: authentication failure
);

TEST_P(LinkTypeConnectionTest, EncryptionChangeEvents) {
  // clang-format off
  auto kEncryptionChangeEventDisabled = CreateStaticByteBuffer(
    0x08,        // HCI Encryption Change event code
    4,           // parameter total size
    0x00,        // status
    0x01, 0x00,  // connection handle: 1
    0x00         // encryption disabled
  );
  auto kEncryptionChangeEventFailed = CreateStaticByteBuffer(
    0x08,        // HCI Encryption Change event code
    4,           // parameter total size
    0x06,        // status: Pin or Key missing
    0x01, 0x00,  // connection handle: 1
    0x00         // encryption disabled
  );

  auto kKeySizeComplete = CreateStaticByteBuffer(
    0x0E,        // event code: Command Complete
    0x07,        // parameters total size
    0xFF,        // num command packets allowed (255)
    0x08, 0x14,  // original opcode

    // return parameters
    0x00,        // status (success)
    0x01, 0x00,  // connection handle: 0x0001
    0x10         // encryption key size: 16
  );
  // clang-format on

  int callback_count = 0;
  auto conn = NewConnection();

  Status status(HostError::kFailed);
  bool enabled = false;
  conn->set_encryption_change_callback([&](Status cb_status, bool cb_enabled) {
    callback_count++;
    status = cb_status;
    enabled = cb_enabled;
  });

  if (conn->ll_type() == Connection::LinkType::kACL) {
    // The host tries to validate the size of key used to encrypt ACL links.
    EXPECT_CMD_PACKET_OUT(test_device(), kReadEncryptionKeySizeCommand, &kKeySizeComplete);
  }

  test_device()->SendCommandChannelPacket(kEncryptionChangeEventEnabled);
  RunLoopUntilIdle();

  EXPECT_EQ(1, callback_count);
  EXPECT_TRUE(status);
  EXPECT_TRUE(enabled);

  test_device()->SendCommandChannelPacket(kEncryptionChangeEventDisabled);
  RunLoopUntilIdle();

  EXPECT_EQ(2, callback_count);
  EXPECT_TRUE(status);
  EXPECT_FALSE(enabled);

  // The host should disconnect the link if encryption fails.
  EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommand);
  test_device()->SendCommandChannelPacket(kEncryptionChangeEventFailed);
  RunLoopUntilIdle();

  EXPECT_EQ(3, callback_count);
  EXPECT_FALSE(status);
  EXPECT_EQ(StatusCode::kPinOrKeyMissing, status.protocol_error());
}

TEST_F(HCI_ConnectionTest, EncryptionFailureNotifiesPeerDisconnectCallback) {
  bool peer_disconnect_callback_received = false;
  auto conn = NewLEConnection();
  conn->set_peer_disconnect_callback([&](auto* self, auto /*reason*/) {
    EXPECT_EQ(conn.get(), self);
    peer_disconnect_callback_received = true;
  });

  // Send the encryption change failure. The host should disconnect the link as a result.
  EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommand);
  test_device()->SendCommandChannelPacket(testing::EncryptionChangeEventPacket(
      hci::StatusCode::kConnectionTerminatedMICFailure, kTestHandle, EncryptionStatus::kOff));
  RunLoopUntilIdle();
  EXPECT_FALSE(peer_disconnect_callback_received);

  // Send the disconnection complete resulting from the encryption failure (this usually does not
  // correspond to the Disconnect command sent by hci::Connection, which will cause a later
  // subsequent event).
  test_device()->SendCommandChannelPacket(testing::DisconnectionCompletePacket(
      kTestHandle, StatusCode::kConnectionTerminatedMICFailure));
  RunLoopUntilIdle();
  EXPECT_TRUE(peer_disconnect_callback_received);
}

TEST_F(HCI_ConnectionTest, AclEncryptionEnableCanNotReadKeySizeClosesLink) {
  auto kKeySizeComplete = CreateStaticByteBuffer(0x0E,        // event code: Command Complete
                                                 0x07,        // parameters total size
                                                 0xFF,        // num command packets allowed (255)
                                                 0x08, 0x14,  // original opcode

                                                 // return parameters
                                                 0x2F,        // status (insufficient security)
                                                 0x01, 0x00,  // connection handle: 0x0001
                                                 0x10         // encryption key size: 16
  );

  int callback_count = 0;
  auto conn = NewACLConnection();
  conn->set_encryption_change_callback([&callback_count](Status status, bool enabled) {
    callback_count++;
    EXPECT_FALSE(status);
    EXPECT_TRUE(enabled);
  });

  EXPECT_CMD_PACKET_OUT(test_device(), kReadEncryptionKeySizeCommand, &kKeySizeComplete);
  EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommand);
  test_device()->SendCommandChannelPacket(kEncryptionChangeEventEnabled);
  RunLoopUntilIdle();

  EXPECT_EQ(1, callback_count);
}

TEST_F(HCI_ConnectionTest, AclEncryptionEnableKeySizeOneByteClosesLink) {
  auto kKeySizeComplete = CreateStaticByteBuffer(0x0E,        // event code: Command Complete
                                                 0x07,        // parameters total size
                                                 0xFF,        // num command packets allowed (255)
                                                 0x08, 0x14,  // original opcode

                                                 // return parameters
                                                 0x00,        // status (success)
                                                 0x01, 0x00,  // connection handle: 0x0001
                                                 0x01         // encryption key size: 1
  );

  int callback_count = 0;
  auto conn = NewACLConnection();
  conn->set_encryption_change_callback([&callback_count](Status status, bool enabled) {
    callback_count++;
    EXPECT_FALSE(status);
    EXPECT_TRUE(enabled);
  });

  EXPECT_CMD_PACKET_OUT(test_device(), kReadEncryptionKeySizeCommand, &kKeySizeComplete);
  EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommand);
  test_device()->SendCommandChannelPacket(kEncryptionChangeEventEnabled);
  RunLoopUntilIdle();

  EXPECT_EQ(1, callback_count);
}

TEST_P(LinkTypeConnectionTest, EncryptionKeyRefreshEvents) {
  // clang-format off
  auto kEncryptionKeyRefresh = CreateStaticByteBuffer(
    0x30,       // HCI Encryption Key Refresh Complete event
    3,          // parameter total size
    0x00,       // status
    0x01, 0x00  // connection handle: 1
  );
  auto kEncryptionKeyRefreshFailed = CreateStaticByteBuffer(
    0x30,       // HCI Encryption Key Refresh Complete event
    3,          // parameter total size
    0x06,       // status: Pin or Key missing
    0x01, 0x00  // connection handle: 1
  );
  // clang-format on

  int callback_count = 0;
  auto conn = NewConnection();

  Status status(HostError::kFailed);
  bool enabled = false;
  conn->set_encryption_change_callback([&](Status cb_status, bool cb_enabled) {
    callback_count++;
    status = cb_status;
    enabled = cb_enabled;
  });

  test_device()->SendCommandChannelPacket(kEncryptionKeyRefresh);
  RunLoopUntilIdle();

  EXPECT_EQ(1, callback_count);
  EXPECT_TRUE(status);
  EXPECT_TRUE(enabled);

  // The host should disconnect the link if encryption fails.
  EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommand);
  test_device()->SendCommandChannelPacket(kEncryptionKeyRefreshFailed);
  RunLoopUntilIdle();

  EXPECT_EQ(2, callback_count);
  EXPECT_FALSE(status);
  EXPECT_EQ(StatusCode::kPinOrKeyMissing, status.protocol_error());
  EXPECT_FALSE(enabled);
}

TEST_F(HCI_ConnectionTest, LELongTermKeyRequestIgnoredEvent) {
  // clang-format off
  auto kMalformed = CreateStaticByteBuffer(
    0x3E,        // LE Meta Event code
    12,          // parameter total size
    0x05,        // LE LTK Request subevent code
    0x01, 0x00,  // connection handle: 1

    // rand:
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    // ediv: (missing 1 byte)
    0x00
  );
  auto kWrongHandle = CreateStaticByteBuffer(
    0x3E,        // LE Meta Event code
    13,          // parameter total size
    0x05,        // LE LTK Request subevent code
    0x02, 0x00,  // connection handle: 2 (wrong)

    // rand: 0
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    // ediv: 0
    0x00, 0x00
  );
  // clang-format on

  auto conn = NewLEConnection();
  conn->set_le_ltk(LinkKey(kLTK, 0, 0));

  test_device()->SendCommandChannelPacket(kMalformed);
  test_device()->SendCommandChannelPacket(kWrongHandle);

  RunLoopUntilIdle();

  // Test will fail if the connection sends a response without ignoring these
  // events.
  EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kTestHandle));
}

TEST_F(HCI_ConnectionTest, LELongTermKeyRequestNoKey) {
  // clang-format off
  auto kEvent = CreateStaticByteBuffer(
    0x3E,        // LE Meta Event code
    13,          // parameter total size
    0x05,        // LE LTK Request subevent code
    0x01, 0x00,  // connection handle: 2 (wrong)

    // rand: 0
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    // ediv: 0
    0x00, 0x00
  );
  auto kResponse = CreateStaticByteBuffer(
    0x1B, 0x20,  // opcode: HCI_LE_Long_Term_Key_Request_Negative_Reply
    2,           // parameter total size
    0x01, 0x00   // connection handle: 1
  );
  // clang-format on

  // The request should be rejected since there is no LTK.
  EXPECT_CMD_PACKET_OUT(test_device(), kResponse);
  auto conn = NewLEConnection();

  test_device()->SendCommandChannelPacket(kEvent);
  RunLoopUntilIdle();
}

// There is a link key but EDiv and Rand values don't match.
TEST_F(HCI_ConnectionTest, LELongTermKeyRequestNoMatchinKey) {
  // clang-format off
  auto kEvent = CreateStaticByteBuffer(
    0x3E,        // LE Meta Event code
    13,          // parameter total size
    0x05,        // LE LTK Request subevent code
    0x01, 0x00,  // connection handle: 2 (wrong)

    // rand: 0
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    // ediv: 0
    0x00, 0x00
  );
  auto kResponse = CreateStaticByteBuffer(
    0x1B, 0x20,  // opcode: HCI_LE_Long_Term_Key_Request_Negative_Reply
    2,           // parameter total size
    0x01, 0x00   // connection handle: 1
  );
  // clang-format on

  // The request should be rejected since there is no LTK.
  EXPECT_CMD_PACKET_OUT(test_device(), kResponse);
  auto conn = NewLEConnection();
  conn->set_le_ltk(LinkKey(kLTK, 1, 1));

  test_device()->SendCommandChannelPacket(kEvent);
  RunLoopUntilIdle();
}

TEST_F(HCI_ConnectionTest, LELongTermKeyRequestReply) {
  // clang-format off
  auto kEvent = CreateStaticByteBuffer(
    0x3E,        // LE Meta Event code
    13,          // parameter total size
    0x05,        // LE LTK Request subevent code
    0x01, 0x00,  // connection handle: 2 (wrong)

    // rand: 0x8899AABBCCDDEEFF
    0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88,
    // ediv: 0xBEEF
    0xEF, 0xBE
  );
  auto kResponse = CreateStaticByteBuffer(
    0x1A, 0x20,  // opcode: HCI_LE_Long_Term_Key_Request_Reply
    18,          // parameter total size
    0x01, 0x00,  // connection handle: 1

    // LTK:
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
  );
  // clang-format on

  // The request should be rejected since there is no LTK.
  EXPECT_CMD_PACKET_OUT(test_device(), kResponse);
  auto conn = NewLEConnection();
  conn->set_le_ltk(LinkKey(kLTK, 0x8899AABBCCDDEEFF, 0xBEEF));

  test_device()->SendCommandChannelPacket(kEvent);
  RunLoopUntilIdle();
}

TEST_F(HCI_ConnectionTest,
       QueuedPacketsGetDroppedOnDisconnectionCompleteAndStalePacketsAreNotSentOnHandleReuse) {
  const ConnectionHandle kHandle = 0x0001;

  // Should register connection with ACL Data Channel.
  auto conn0 = NewACLConnection(Connection::Role::kMaster, kHandle);

  testing::MockController::DataCallback data_cb = [](const ByteBuffer& packet) {};
  size_t packet_count = 0;
  auto data_cb_wrapper = [&data_cb, &packet_count](const ByteBuffer& packet) {
    packet_count++;
    ASSERT_EQ(packet.size(), sizeof(ACLDataHeader) + 1);
    data_cb(packet);
  };
  test_device()->SetDataCallback(data_cb_wrapper, dispatcher());

  const uint8_t payload0 = 0x01;
  data_cb = [payload0](const ByteBuffer& packet) {
    EXPECT_EQ(packet[sizeof(ACLDataHeader)], payload0);
  };

  // Fill controller buffer, + 1 packet in queue.
  for (size_t i = 0; i < kBrEdrBufferInfo.max_num_packets() + 1; i++) {
    auto packet = ACLDataPacket::New(kHandle, ACLPacketBoundaryFlag::kFirstNonFlushable,
                                     ACLBroadcastFlag::kPointToPoint, 1);
    packet->mutable_view()->mutable_payload_bytes()[0] = payload0;
    EXPECT_TRUE(acl_data_channel()->SendPacket(std::move(packet), l2cap::kInvalidChannelId,
                                               AclDataChannel::PacketPriority::kLow));
  }

  // Run until the data is flushed out to the MockController.
  RunLoopUntilIdle();

  // Only packets that fit in buffer should have been received.
  EXPECT_EQ(packet_count, kBrEdrBufferInfo.max_num_packets());

  // All future packets received should be for the next connection.
  const uint8_t payload1 = 0x02;
  data_cb = [payload1](const ByteBuffer& packet) {
    EXPECT_EQ(packet[sizeof(ACLDataHeader)], payload1);
  };

  const auto disconnect_status_rsp = testing::DisconnectStatusResponsePacket();
  DynamicByteBuffer disconnection_complete(testing::DisconnectionCompletePacket(kHandle));
  EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kHandle), &disconnect_status_rsp,
                        &disconnection_complete);

  // Disconnect |conn0| by destroying it. The received disconnection complete event will cause the
  // handler to unregister the link and clear pending packets.
  conn0.reset();
  RunLoopUntilIdle();

  // Register connection with same handle.
  auto conn1 = NewACLConnection(Connection::Role::kMaster, kHandle);

  // Fill controller buffer, + 1 packet in queue.
  for (size_t i = 0; i < kBrEdrBufferInfo.max_num_packets(); i++) {
    auto packet = ACLDataPacket::New(kHandle, ACLPacketBoundaryFlag::kFirstNonFlushable,
                                     ACLBroadcastFlag::kPointToPoint, 1);
    packet->mutable_view()->mutable_payload_bytes()[0] = payload1;
    EXPECT_TRUE(acl_data_channel()->SendPacket(std::move(packet), l2cap::kInvalidChannelId,
                                               AclDataChannel::PacketPriority::kLow));
  }

  RunLoopUntilIdle();

  EXPECT_EQ(packet_count, 2 * kBrEdrBufferInfo.max_num_packets());

  conn1.reset();
  EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kHandle), &disconnect_status_rsp,
                        &disconnection_complete);
  RunLoopUntilIdle();
}

TEST_F(HCI_ConnectionTest, PeerDisconnectCallback) {
  const ConnectionHandle kHandle = 0x0001;

  auto conn = NewACLConnection(Connection::Role::kMaster, kHandle);

  size_t cb_count = 0;
  auto disconn_complete_cb = [&](const Connection* cb_conn, auto /*reason*/) {
    ASSERT_TRUE(cb_conn);
    cb_count++;

    // Should be safe to destroy connection from this callback, as a connection manager does.
    conn.reset();
  };
  conn->set_peer_disconnect_callback(disconn_complete_cb);

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

  DynamicByteBuffer disconnection_complete(testing::DisconnectionCompletePacket(kHandle));
  test_device()->SendCommandChannelPacket(disconnection_complete);
  RunLoopUntilIdle();

  EXPECT_EQ(1u, cb_count);
}

// Test connection handling cases for all types of links.
INSTANTIATE_TEST_SUITE_P(HCI_ConnectionTest, LinkTypeConnectionTest,
                         ::testing::Values(Connection::LinkType::kACL, Connection::LinkType::kLE));

}  // namespace
}  // namespace bt::hci
