// 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/fake_controller_test.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/test_controller.h"

namespace bt {
namespace gap {
namespace {

using testing::CommandTransaction;
using testing::TestController;

using TestingBase = testing::FakeControllerTest<TestController>;

const DeviceAddress kPublic(DeviceAddress::Type::kLEPublic,
                            "AA:BB:CC:DD:EE:FF");

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());
    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
      );
  test_device()->QueueCommandTransaction(
      CommandTransaction(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.
  test_device()->QueueCommandTransaction(
      CommandTransaction(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
      );
  test_device()->QueueCommandTransaction(
      CommandTransaction(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
      );
  test_device()->QueueCommandTransaction(
      CommandTransaction(hci::kLESetRandomAddress, {&kErrorResponse}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(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
      );
  test_device()->QueueCommandTransaction(
      CommandTransaction(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
      );
  test_device()->QueueCommandTransaction(
      CommandTransaction(hci::kLESetRandomAddress, {&kSuccessResponse}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(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
      );
  test_device()->QueueCommandTransaction(
      CommandTransaction(hci::kLESetRandomAddress, {&kSuccessResponse}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(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
      );
  test_device()->QueueCommandTransaction(
      CommandTransaction(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
      );
  test_device()->QueueCommandTransaction(
      CommandTransaction(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 gap
}  // namespace bt
