// Copyright 2018 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 "low_energy_address_manager.h"

#include <fbl/function.h>

#include "gap.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/util.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/controller_test.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/mock_controller.h"

namespace bt::gap {
namespace {

using testing::CommandTransaction;
using testing::MockController;

using TestingBase = testing::ControllerTest<MockController>;

const DeviceAddress kPublic(DeviceAddress::Type::kLEPublic, {0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA});

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

 protected:
  void SetUp() override {
    TestingBase::SetUp();
    addr_mgr_ = std::make_unique<LowEnergyAddressManager>(
        kPublic, [this] { return IsRandomAddressChangeAllowed(); }, transport()->WeakPtr());
    ASSERT_EQ(kPublic, addr_mgr()->identity_address());
    ASSERT_FALSE(addr_mgr()->irk());
    StartTestDevice();
  }

  void TearDown() override {
    addr_mgr_ = nullptr;
    TestingBase::TearDown();
  }

  DeviceAddress EnsureLocalAddress() {
    bool called = false;
    DeviceAddress result;
    addr_mgr()->EnsureLocalAddress([&](const auto& addr) {
      result = addr;
      called = true;
    });
    RunLoopUntilIdle();
    EXPECT_TRUE(called);
    return result;
  }

  // Called by |addr_mgr_|.
  bool IsRandomAddressChangeAllowed() const { return random_address_change_allowed_; }

  LowEnergyAddressManager* addr_mgr() const { return addr_mgr_.get(); };

  void set_random_address_change_allowed(bool value) { random_address_change_allowed_ = value; }

 private:
  std::unique_ptr<LowEnergyAddressManager> addr_mgr_;
  bool random_address_change_allowed_ = true;

  DISALLOW_COPY_ASSIGN_AND_MOVE(GAP_LowEnergyAddressManagerTest);
};

TEST_F(GAP_LowEnergyAddressManagerTest, DefaultState) { EXPECT_EQ(kPublic, EnsureLocalAddress()); }

TEST_F(GAP_LowEnergyAddressManagerTest, EnablePrivacy) {
  // Respond with success.
  const auto kResponse = CreateStaticByteBuffer(0x0E, 4,     // Command Complete, 4 bytes,
                                                1,           // 1 allowed packet
                                                0x05, 0x20,  // opcode: HCI_LE_Set_Random_Address
                                                0x00         // status: success
  );
  EXPECT_CMD_PACKET_OUT(test_device(), hci::kLESetRandomAddress, &kResponse);

  const UInt128 kIrk{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
  int hci_cmd_count = 0;
  DeviceAddress addr;
  test_device()->SetTransactionCallback(
      [&](const auto& rx) {
        hci_cmd_count++;

        const auto addr_bytes = rx.view(sizeof(hci::CommandHeader));
        ASSERT_EQ(6u, addr_bytes.size());
        addr = DeviceAddress(DeviceAddress::Type::kLERandom, DeviceAddressBytes(addr_bytes));
      },
      dispatcher());

  addr_mgr()->set_irk(kIrk);
  ASSERT_TRUE(addr_mgr()->irk());
  EXPECT_EQ(kIrk, *addr_mgr()->irk());
  addr_mgr()->EnablePrivacy(true);

  // Privacy is now considered enabled. Further requests to enable should not
  // trigger additional HCI commands.
  addr_mgr()->EnablePrivacy(true);
  RunLoopUntilIdle();

  // We should have received a HCI command with a RPA resolvable using |kIrk|.
  EXPECT_EQ(1, hci_cmd_count);
  EXPECT_TRUE(addr.IsResolvablePrivate());
  EXPECT_TRUE(sm::util::IrkCanResolveRpa(kIrk, addr));

  // The new random address should be returned.
  EXPECT_EQ(addr, EnsureLocalAddress());

  // Assign a new IRK. The new address should be used when it gets refreshed.
  // Re-enable privacy with a new IRK. The latest IRK should be used.
  const UInt128 kIrk2{{15, 14, 14, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}};
  addr_mgr()->set_irk(kIrk2);
  ASSERT_TRUE(addr_mgr()->irk());
  EXPECT_EQ(kIrk2, *addr_mgr()->irk());

  // Returns the same address.
  EXPECT_EQ(addr, EnsureLocalAddress());
  EXPECT_FALSE(sm::util::IrkCanResolveRpa(kIrk2, addr));

  // Re-enable privacy to trigger a refresh.
  EXPECT_CMD_PACKET_OUT(test_device(), hci::kLESetRandomAddress, &kResponse);
  addr_mgr()->EnablePrivacy(false);
  addr_mgr()->EnablePrivacy(true);
  RunLoopUntilIdle();

  EXPECT_EQ(addr, EnsureLocalAddress());
  EXPECT_TRUE(addr.IsResolvablePrivate());
  EXPECT_TRUE(sm::util::IrkCanResolveRpa(kIrk2, addr));
}

TEST_F(GAP_LowEnergyAddressManagerTest, EnablePrivacyNoIrk) {
  // Respond with success.
  const auto kResponse = CreateStaticByteBuffer(0x0E, 4,     // Command Complete, 4 bytes,
                                                1,           // 1 allowed packet
                                                0x05, 0x20,  // opcode: HCI_LE_Set_Random_Address
                                                0x00         // status: success
  );
  EXPECT_CMD_PACKET_OUT(test_device(), hci::kLESetRandomAddress, &kResponse);

  int hci_cmd_count = 0;
  DeviceAddress addr;
  test_device()->SetTransactionCallback(
      [&](const auto& rx) {
        hci_cmd_count++;

        const auto addr_bytes = rx.view(sizeof(hci::CommandHeader));
        ASSERT_EQ(6u, addr_bytes.size());
        addr = DeviceAddress(DeviceAddress::Type::kLERandom, DeviceAddressBytes(addr_bytes));
      },
      dispatcher());

  addr_mgr()->EnablePrivacy(true);

  // Privacy is now considered enabled. Further requests to enable should not
  // trigger additional HCI commands.
  addr_mgr()->EnablePrivacy(true);
  RunLoopUntilIdle();

  // We should have received a HCI command with a NRPA.
  EXPECT_EQ(1, hci_cmd_count);
  EXPECT_TRUE(addr.IsNonResolvablePrivate());

  // The new random address should be returned.
  EXPECT_EQ(addr, EnsureLocalAddress());
}

TEST_F(GAP_LowEnergyAddressManagerTest, EnablePrivacyHciError) {
  // Respond with error.
  const auto kErrorResponse =
      CreateStaticByteBuffer(0x0E, 4,     // Command Complete, 4 bytes,
                             1,           // 1 allowed packet
                             0x05, 0x20,  // opcode: HCI_LE_Set_Random_Address
                             0x0C         // status: Command Disallowed
      );
  // The second time respond with success.
  const auto kSuccessResponse =
      CreateStaticByteBuffer(0x0E, 4,     // Command Complete, 4 bytes,
                             1,           // 1 allowed packet
                             0x05, 0x20,  // opcode: HCI_LE_Set_Random_Address
                             0x00         // status: success
      );
  EXPECT_CMD_PACKET_OUT(test_device(), hci::kLESetRandomAddress, &kErrorResponse);
  EXPECT_CMD_PACKET_OUT(test_device(), hci::kLESetRandomAddress, &kSuccessResponse);

  addr_mgr()->EnablePrivacy(true);

  // Request the new address and run the event loop. The old address should be
  // returned due to the failure.
  EXPECT_EQ(kPublic, EnsureLocalAddress());

  // Requesting the address a second time while address update is disallowed
  // should return the old address without sending HCI commands.
  int hci_count = 0;
  test_device()->SetTransactionCallback([&] { hci_count++; }, dispatcher());
  set_random_address_change_allowed(false);
  EXPECT_EQ(kPublic, EnsureLocalAddress());
  EXPECT_EQ(0, hci_count);

  // Requesting the address a third time while address update is allowed should
  // configure and return the new address.
  set_random_address_change_allowed(true);
  EXPECT_TRUE(EnsureLocalAddress().IsNonResolvablePrivate());
  EXPECT_EQ(1, hci_count);
}

TEST_F(GAP_LowEnergyAddressManagerTest, EnablePrivacyWhileAddressChangeIsDisallowed) {
  const auto kSuccessResponse =
      CreateStaticByteBuffer(0x0E, 4,     // Command Complete, 4 bytes,
                             1,           // 1 allowed packet
                             0x05, 0x20,  // opcode: HCI_LE_Set_Random_Address
                             0x00         // status: success
      );
  EXPECT_CMD_PACKET_OUT(test_device(), hci::kLESetRandomAddress, &kSuccessResponse);

  int hci_count = 0;
  test_device()->SetTransactionCallback([&] { hci_count++; }, dispatcher());
  set_random_address_change_allowed(false);

  // No HCI commands should be sent while disallowed.
  addr_mgr()->EnablePrivacy(true);
  RunLoopUntilIdle();
  EXPECT_EQ(0, hci_count);

  EXPECT_EQ(kPublic, EnsureLocalAddress());
  EXPECT_EQ(0, hci_count);

  // Requesting the address while address change is allowed should configure and
  // return the new address.
  set_random_address_change_allowed(true);
  EXPECT_TRUE(EnsureLocalAddress().IsNonResolvablePrivate());
  EXPECT_EQ(1, hci_count);
}

TEST_F(GAP_LowEnergyAddressManagerTest, AddressExpiration) {
  const auto kSuccessResponse =
      CreateStaticByteBuffer(0x0E, 4,     // Command Complete, 4 bytes,
                             1,           // 1 allowed packet
                             0x05, 0x20,  // opcode: HCI_LE_Set_Random_Address
                             0x00         // status: success
      );
  EXPECT_CMD_PACKET_OUT(test_device(), hci::kLESetRandomAddress, &kSuccessResponse);
  EXPECT_CMD_PACKET_OUT(test_device(), hci::kLESetRandomAddress, &kSuccessResponse);

  addr_mgr()->EnablePrivacy(true);
  auto addr1 = EnsureLocalAddress();
  EXPECT_TRUE(addr1.IsNonResolvablePrivate());

  // Requesting the address again should keep returning the same address without
  // sending any HCI commands.
  int hci_count = 0;
  test_device()->SetTransactionCallback([&] { hci_count++; }, dispatcher());
  EXPECT_EQ(addr1, EnsureLocalAddress());
  EXPECT_EQ(addr1, EnsureLocalAddress());
  EXPECT_EQ(addr1, EnsureLocalAddress());
  EXPECT_EQ(addr1, EnsureLocalAddress());
  EXPECT_EQ(addr1, EnsureLocalAddress());
  EXPECT_EQ(0, hci_count);

  // A new address should be generated and configured after the random address
  // interval.
  RunLoopFor(kPrivateAddressTimeout);
  EXPECT_EQ(1, hci_count);

  // Requesting the address again should return the new address.
  auto addr2 = EnsureLocalAddress();
  EXPECT_TRUE(addr2.IsNonResolvablePrivate());
  EXPECT_NE(addr1, addr2);
  EXPECT_EQ(1, hci_count);
}

TEST_F(GAP_LowEnergyAddressManagerTest, AddressExpirationWhileAddressChangeIsDisallowed) {
  const auto kSuccessResponse =
      CreateStaticByteBuffer(0x0E, 4,     // Command Complete, 4 bytes,
                             1,           // 1 allowed packet
                             0x05, 0x20,  // opcode: HCI_LE_Set_Random_Address
                             0x00         // status: success
      );
  EXPECT_CMD_PACKET_OUT(test_device(), hci::kLESetRandomAddress, &kSuccessResponse);
  EXPECT_CMD_PACKET_OUT(test_device(), hci::kLESetRandomAddress, &kSuccessResponse);

  addr_mgr()->EnablePrivacy(true);
  auto addr1 = EnsureLocalAddress();
  EXPECT_TRUE(addr1.IsNonResolvablePrivate());

  // Requesting the address again should keep returning the same address without
  // sending any HCI commands.
  int hci_count = 0;
  test_device()->SetTransactionCallback([&] { hci_count++; }, dispatcher());
  EXPECT_EQ(addr1, EnsureLocalAddress());
  EXPECT_EQ(addr1, EnsureLocalAddress());
  EXPECT_EQ(addr1, EnsureLocalAddress());
  EXPECT_EQ(addr1, EnsureLocalAddress());
  EXPECT_EQ(addr1, EnsureLocalAddress());
  EXPECT_EQ(0, hci_count);

  // After the interval ends, the address should be marked as expired but should
  // not send an HCI command while the command is disallowed.
  set_random_address_change_allowed(false);
  RunLoopFor(kPrivateAddressTimeout);
  EXPECT_EQ(addr1, EnsureLocalAddress());
  EXPECT_EQ(0, hci_count);

  // Requesting the address again while the command is allowed should configure
  // and return the new address.
  set_random_address_change_allowed(true);
  auto addr2 = EnsureLocalAddress();
  EXPECT_TRUE(addr2.IsNonResolvablePrivate());
  EXPECT_NE(addr1, addr2);
  EXPECT_EQ(1, hci_count);
}

TEST_F(GAP_LowEnergyAddressManagerTest, DisablePrivacy) {
  // Enable privacy.
  const auto kSuccessResponse =
      CreateStaticByteBuffer(0x0E, 4,     // Command Complete, 4 bytes,
                             1,           // 1 allowed packet
                             0x05, 0x20,  // opcode: HCI_LE_Set_Random_Address
                             0x00         // status: success
      );
  EXPECT_CMD_PACKET_OUT(test_device(), hci::kLESetRandomAddress, &kSuccessResponse);

  addr_mgr()->EnablePrivacy(true);
  EXPECT_TRUE(EnsureLocalAddress().IsNonResolvablePrivate());

  // Disable privacy.
  addr_mgr()->EnablePrivacy(false);

  // The public address should be returned for the local address.
  EXPECT_EQ(DeviceAddress::Type::kLEPublic, EnsureLocalAddress().type());

  // No HCI commands should get sent after private address interval expires.
  int hci_count = 0;
  test_device()->SetTransactionCallback([&] { hci_count++; }, dispatcher());
  RunLoopFor(kPrivateAddressTimeout);
  EXPECT_EQ(0, hci_count);
  EXPECT_EQ(DeviceAddress::Type::kLEPublic, EnsureLocalAddress().type());
}

TEST_F(GAP_LowEnergyAddressManagerTest, DisablePrivacyDuringAddressChange) {
  const auto kSuccessResponse =
      CreateStaticByteBuffer(0x0E, 4,     // Command Complete, 4 bytes,
                             1,           // 1 allowed packet
                             0x05, 0x20,  // opcode: HCI_LE_Set_Random_Address
                             0x00         // status: success
      );
  EXPECT_CMD_PACKET_OUT(test_device(), hci::kLESetRandomAddress, &kSuccessResponse);

  int hci_count = 0;
  test_device()->SetTransactionCallback([&] { hci_count++; }, dispatcher());

  // Enable and disable in quick succession. HCI command should be sent but the
  // local address shouldn't take effect.
  addr_mgr()->EnablePrivacy(true);
  addr_mgr()->EnablePrivacy(false);
  EXPECT_EQ(DeviceAddress::Type::kLEPublic, EnsureLocalAddress().type());
  EXPECT_EQ(1, hci_count);

  // No HCI commands should get sent after private address interval expires.
  RunLoopFor(kPrivateAddressTimeout);
  EXPECT_EQ(1, hci_count);
  EXPECT_EQ(DeviceAddress::Type::kLEPublic, EnsureLocalAddress().type());
}

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