// 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/legacy_low_energy_advertiser.h"

#include <fbl/macros.h>

#include "src/connectivity/bluetooth/core/bt-host/common/advertising_data.h"
#include "src/connectivity/bluetooth/core/bt-host/common/device_address.h"
#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/common/uuid.h"
#include "src/connectivity/bluetooth/core/bt-host/hci-spec/defaults.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/fake_connection.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/controller_test.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/fake_controller.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/fake_peer.h"

namespace bt {

using testing::FakeController;
using testing::FakePeer;

namespace hci {

using AdvertisingOptions = LegacyLowEnergyAdvertiser::AdvertisingOptions;

namespace {

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

constexpr ConnectionHandle kHandle = 0x0001;

const DeviceAddress kPublicAddress(DeviceAddress::Type::kLEPublic, {1});
const DeviceAddress kRandomAddress(DeviceAddress::Type::kLERandom, {2});

constexpr AdvertisingIntervalRange kTestInterval(kLEAdvertisingIntervalMin,
                                                 kLEAdvertisingIntervalMax);

void NopConnectionCallback(ConnectionPtr) {}

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

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

    // ACL data channel needs to be present for production hci::Connection
    // objects.
    TestingBase::InitializeACLDataChannel(hci::DataBufferInfo(),
                                          hci::DataBufferInfo(hci::kMaxACLPayloadSize, 10));

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

    advertiser_ = std::make_unique<LegacyLowEnergyAdvertiser>(transport()->WeakPtr());

    test_device()->StartCmdChannel(test_cmd_chan());
    test_device()->StartAclChannel(test_acl_chan());
  }

  void TearDown() override {
    advertiser_ = nullptr;
    test_device()->Stop();
    TestingBase::TearDown();
  }

  LegacyLowEnergyAdvertiser* advertiser() const { return advertiser_.get(); }

  StatusCallback GetSuccessCallback() {
    return [this](Status status) {
      last_status_ = status;
      EXPECT_TRUE(status) << status.ToString();
    };
  }

  StatusCallback GetErrorCallback() {
    return [this](Status status) {
      last_status_ = status;
      EXPECT_FALSE(status);
    };
  }

  // Retrieves the last status, and resets the last status to empty.
  std::optional<Status> MoveLastStatus() { return std::move(last_status_); }

  // Makes some fake advertising data.
  // |include_flags| signals whether to include flag encoding size in the data calculation.
  AdvertisingData GetExampleData(bool include_flags = true) {
    AdvertisingData result;

    auto name = "fuchsia";
    EXPECT_TRUE(result.SetLocalName(name));

    auto appearance = 0x1234;
    result.SetAppearance(appearance);

    EXPECT_LE(result.CalculateBlockSize(include_flags), kMaxLEAdvertisingDataLength);

    return result;
  }

  // Makes fake advertising data that is too large.
  // |include_flags| signals whether to include flag encoding size in the data calculation.
  AdvertisingData GetTooLargeExampleData(bool include_tx_power, bool include_flags) {
    AdvertisingData result;

    std::string name;
    if (include_tx_power && include_flags) {
      // |name| is 24 bytes. In TLV Format, this would require 1 + 1 + 24 = 26 bytes to serialize.
      // The TX Power is encoded as 3 bytes.
      // The flags are encoded |kFlagsSize| = 3 bytes.
      // Total = 32 bytes.
      result.SetTxPower(3);
      name = "fuchsiafuchsiafuchsia123";
    } else if (!include_tx_power && !include_flags) {
      // |name| is 30 bytes. In TLV Format, this would require 32 bytes to serialize.
      name = "fuchsiafuchsiafuchsiafuchsia12";
    } else {
      if (include_tx_power)
        result.SetTxPower(3);
      // |name| 27 bytes: 29 bytes to serialize.
      // |TX Power| OR |flags|: 3 bytes to serialize.
      // Total = 32 bytes.
      name = "fuchsiafuchsiafuchsia123456";
    }
    EXPECT_TRUE(result.SetLocalName(name));

    // The maximum advertisement packet is: |kMaxLEAdvertisingDataLength| = 31, and |result| = 32
    // bytes. |result| should be too large to advertise.
    EXPECT_GT(result.CalculateBlockSize(include_flags), kMaxLEAdvertisingDataLength);

    return result;
  }

 private:
  std::unique_ptr<LegacyLowEnergyAdvertiser> advertiser_;

  std::optional<Status> last_status_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(HCI_LegacyLowEnergyAdvertiserTest);
};

// TODO(jamuraa): Use typed tests to test LowEnergyAdvertiser common properties

// - Stops the advertisement when an incoming connection comes
// - Calls the connection callback correctly when it's setup
// - Checks that advertising state is cleaned up.
// - Checks that it is possible to restart advertising.
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, ConnectionTest) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data;
  AdvertisingOptions options(kTestInterval, /*anonymous=*/false, kDefaultNoAdvFlags, false);

  ConnectionPtr link;
  auto conn_cb = [&link](auto cb_link) { link = std::move(cb_link); };

  advertiser()->StartAdvertising(kPublicAddress, ad, scan_data, options, conn_cb,
                                 GetSuccessCallback());
  RunLoopUntilIdle();
  EXPECT_TRUE(MoveLastStatus());

  // The connection manager will hand us a connection when one gets created.
  advertiser()->OnIncomingConnection(kHandle, Connection::Role::kSlave, kRandomAddress,
                                     LEConnectionParameters());
  ASSERT_TRUE(link);
  EXPECT_EQ(kHandle, link->handle());
  EXPECT_EQ(kPublicAddress, link->local_address());
  EXPECT_EQ(kRandomAddress, link->peer_address());
  link->Disconnect(StatusCode::kRemoteUserTerminatedConnection);
  test_device()->SendDisconnectionCompleteEvent(link->handle());

  // Advertising state should get cleared.
  RunLoopUntilIdle();

  // StopAdvertising() sends multiple HCI commands. We only check that the
  // first one succeeded. StartAdvertising cancels the rest of the sequence
  // below.
  EXPECT_FALSE(test_device()->le_advertising_state().enabled);

  // Restart advertising using kRandomAddress.
  advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, conn_cb,
                                 GetSuccessCallback());
  RunLoopUntilIdle();
  EXPECT_TRUE(MoveLastStatus());
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);

  // Accept a connection from kPublicAddress. The local and peer addresses
  // should get assigned correctly.
  advertiser()->OnIncomingConnection(kHandle, Connection::Role::kSlave, kPublicAddress,
                                     LEConnectionParameters());
  // ASSERT_TRUE(link);
  EXPECT_EQ(kRandomAddress, link->local_address());
  EXPECT_EQ(kPublicAddress, link->peer_address());
  link->Disconnect(StatusCode::kRemoteUserTerminatedConnection);
}

// Tests that advertising can be restarted right away in a connection callback.
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, RestartInConnectionCallback) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data;
  AdvertisingOptions options(kTestInterval, false, kDefaultNoAdvFlags, false);

  ConnectionPtr link;
  auto conn_cb = [&, this](auto cb_link) {
    link = std::move(cb_link);
    advertiser()->StartAdvertising(kPublicAddress, ad, scan_data, options, NopConnectionCallback,
                                   GetSuccessCallback());
  };

  advertiser()->StartAdvertising(kPublicAddress, ad, scan_data, options, conn_cb,
                                 GetSuccessCallback());
  RunLoopUntilIdle();
  EXPECT_TRUE(MoveLastStatus());
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);

  bool enabled = true;
  std::vector<bool> adv_states;
  test_device()->set_advertising_state_callback([this, &adv_states, &enabled] {
    bool new_enabled = test_device()->le_advertising_state().enabled;
    if (enabled != new_enabled) {
      adv_states.push_back(new_enabled);
      enabled = new_enabled;
    }
  });

  advertiser()->OnIncomingConnection(kHandle, Connection::Role::kSlave, kRandomAddress,
                                     LEConnectionParameters());

  // Advertising should get disabled and re-enabled.
  RunLoopUntilIdle();
  ASSERT_EQ(2u, adv_states.size());
  EXPECT_FALSE(adv_states[0]);
  EXPECT_TRUE(adv_states[1]);
}

// An incoming connection when not advertising should get disconnected.
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, IncomingConnectionWhenNotAdvertising) {
  std::vector<std::pair<bool, ConnectionHandle>> connection_states;
  test_device()->set_connection_state_callback(
      [&](const auto& address, auto handle, bool connected, bool canceled) {
        EXPECT_EQ(kRandomAddress, address);
        EXPECT_FALSE(canceled);
        connection_states.push_back(std::make_pair(connected, handle));
      });

  auto fake_peer = std::make_unique<FakePeer>(kRandomAddress, true, true);
  test_device()->AddPeer(std::move(fake_peer));
  test_device()->ConnectLowEnergy(kRandomAddress, ConnectionRole::kSlave);
  RunLoopUntilIdle();

  ASSERT_EQ(1u, connection_states.size());
  auto [connection_state, handle] = connection_states[0];
  EXPECT_TRUE(connection_state);

  // Notify the advertiser of the incoming connection. It should reject it and the controller should
  // become disconnected.
  advertiser()->OnIncomingConnection(handle, Connection::Role::kSlave, kRandomAddress,
                                     LEConnectionParameters());
  RunLoopUntilIdle();
  ASSERT_EQ(2u, connection_states.size());
  auto [connection_state_after_disconnect, disconnected_handle] = connection_states[1];
  EXPECT_EQ(handle, disconnected_handle);
  EXPECT_FALSE(connection_state_after_disconnect);
}

// An incoming connection during non-connectable advertising should get disconnected.
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, IncomingConnectionWhenNonConnectableAdvertising) {
  AdvertisingData empty;
  AdvertisingData scan_rsp_empty;
  AdvertisingOptions options(kTestInterval, false, kDefaultNoAdvFlags, false);
  advertiser()->StartAdvertising(kPublicAddress, empty, scan_rsp_empty, options, nullptr,
                                 GetSuccessCallback());
  RunLoopUntilIdle();
  ASSERT_TRUE(MoveLastStatus());

  std::vector<std::pair<bool, ConnectionHandle>> connection_states;
  test_device()->set_connection_state_callback(
      [&](const auto& address, auto handle, bool connected, bool canceled) {
        EXPECT_EQ(kRandomAddress, address);
        EXPECT_FALSE(canceled);
        connection_states.push_back(std::make_pair(connected, handle));
      });

  auto fake_peer = std::make_unique<FakePeer>(kRandomAddress, true, true);
  test_device()->AddPeer(std::move(fake_peer));
  test_device()->ConnectLowEnergy(kRandomAddress, ConnectionRole::kSlave);
  RunLoopUntilIdle();

  ASSERT_EQ(1u, connection_states.size());
  auto [connection_state, handle] = connection_states[0];
  EXPECT_TRUE(connection_state);

  // Notify the advertiser of the incoming connection. It should reject it and the controller should
  // become disconnected.
  advertiser()->OnIncomingConnection(handle, Connection::Role::kSlave, kRandomAddress,
                                     LEConnectionParameters());
  RunLoopUntilIdle();
  ASSERT_EQ(2u, connection_states.size());
  auto [connection_state_after_disconnect, disconnected_handle] = connection_states[1];
  EXPECT_EQ(handle, disconnected_handle);
  EXPECT_FALSE(connection_state_after_disconnect);
}

// Tests starting and stopping an advertisement.
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, StartAndStop) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data;
  AdvertisingOptions options(kTestInterval, false, kDefaultNoAdvFlags, false);

  advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                 GetSuccessCallback());
  RunLoopUntilIdle();
  EXPECT_TRUE(MoveLastStatus());
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);

  EXPECT_TRUE(advertiser()->StopAdvertising(kRandomAddress));
  RunLoopUntilIdle();
  EXPECT_FALSE(test_device()->le_advertising_state().enabled);
}

// Tests that an advertisement is configured with the correct parameters.
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, AdvertisingParameters) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data;
  auto flags = AdvFlag::kLEGeneralDiscoverableMode;
  AdvertisingOptions options(kTestInterval, false, flags, false);

  advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                 GetSuccessCallback());
  RunLoopUntilIdle();
  EXPECT_TRUE(MoveLastStatus());

  // The expected advertisement including the Flags.
  DynamicByteBuffer expected_ad(ad.CalculateBlockSize(/*include_flags*/ true));
  ad.WriteBlock(&expected_ad, flags);

  // Verify the fake controller state.
  const auto& fake_adv_state = test_device()->le_advertising_state();
  EXPECT_TRUE(fake_adv_state.enabled);
  EXPECT_EQ(kTestInterval.min(), fake_adv_state.interval_min);
  EXPECT_EQ(kTestInterval.max(), fake_adv_state.interval_max);
  EXPECT_EQ(expected_ad, fake_adv_state.advertised_view());
  EXPECT_EQ(0u, fake_adv_state.scan_rsp_view().size());
  EXPECT_EQ(hci::LEOwnAddressType::kRandom, fake_adv_state.own_address_type);

  // Restart advertising with a public address and verify that the configured
  // local address type is correct.
  EXPECT_TRUE(advertiser()->StopAdvertising(kRandomAddress));
  AdvertisingOptions new_options(kTestInterval, false, kDefaultNoAdvFlags, false);
  advertiser()->StartAdvertising(kPublicAddress, ad, scan_data, new_options, nullptr,
                                 GetSuccessCallback());
  RunLoopUntilIdle();
  EXPECT_TRUE(MoveLastStatus());
  EXPECT_TRUE(fake_adv_state.enabled);
  EXPECT_EQ(hci::LEOwnAddressType::kPublic, fake_adv_state.own_address_type);
}

TEST_F(HCI_LegacyLowEnergyAdvertiserTest, AdvertisingDataTooLong) {
  AdvertisingData invalid_ad =
      GetTooLargeExampleData(/*include_tx_power=*/false, /*include_flags=*/true);
  AdvertisingData valid_scan_rsp = GetExampleData(/*include_flags=*/false);
  AdvertisingOptions options(kTestInterval, false, kDefaultNoAdvFlags, false);

  // Advertising data too large.
  advertiser()->StartAdvertising(kRandomAddress, invalid_ad, valid_scan_rsp, options, nullptr,
                                 GetErrorCallback());
  RunLoopUntilIdle();
  auto status = MoveLastStatus();
  ASSERT_TRUE(status);
  EXPECT_EQ(HostError::kAdvertisingDataTooLong, status->error());

  // Check with TX Power included.
  invalid_ad = GetTooLargeExampleData(/*include_tx_power=*/true, /*include_flags=*/true);
  advertiser()->StartAdvertising(kRandomAddress, invalid_ad, valid_scan_rsp, options, nullptr,
                                 GetErrorCallback());
  RunLoopUntilIdle();
  status = MoveLastStatus();
  ASSERT_TRUE(status);
  EXPECT_EQ(HostError::kAdvertisingDataTooLong, status->error());
}

TEST_F(HCI_LegacyLowEnergyAdvertiserTest, ScanResponseTooLong) {
  AdvertisingData valid_ad = GetExampleData();
  AdvertisingData invalid_scan_rsp =
      GetTooLargeExampleData(/*include_tx_power=*/false, /*include_flags=*/false);
  AdvertisingOptions options(kTestInterval, false, kDefaultNoAdvFlags, false);
  advertiser()->StartAdvertising(kRandomAddress, valid_ad, invalid_scan_rsp, options, nullptr,
                                 GetErrorCallback());
  RunLoopUntilIdle();
  auto status = MoveLastStatus();
  ASSERT_TRUE(status);
  EXPECT_EQ(HostError::kScanResponseTooLong, status->error());

  // Check with TX Power included.
  invalid_scan_rsp = GetTooLargeExampleData(/*include_tx_power=*/true, /*include_flags=*/false);
  advertiser()->StartAdvertising(kRandomAddress, valid_ad, invalid_scan_rsp, options, nullptr,
                                 GetErrorCallback());
  RunLoopUntilIdle();
  status = MoveLastStatus();
  ASSERT_TRUE(status);
  EXPECT_EQ(HostError::kScanResponseTooLong, status->error());
}

// Tests that advertising interval values are capped within the allowed range.
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, AdvertisingIntervalWithinAllowedRange) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data;

  // Pass min and max values that are outside the allowed range. These should be capped.
  constexpr AdvertisingIntervalRange interval(0x0000, 0xFFFF);
  AdvertisingOptions options(interval, false, kDefaultNoAdvFlags, false);
  advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                 GetSuccessCallback());
  RunLoopUntilIdle();
  EXPECT_TRUE(MoveLastStatus());

  const auto& fake_adv_state = test_device()->le_advertising_state();
  EXPECT_EQ(kLEAdvertisingIntervalMin, fake_adv_state.interval_min);
  EXPECT_EQ(kLEAdvertisingIntervalMax, fake_adv_state.interval_max);

  // Reconfigure with values that are within the range. These should get passed down as is.
  const AdvertisingIntervalRange new_interval(kLEAdvertisingIntervalMin + 1,
                                              kLEAdvertisingIntervalMax - 1);
  AdvertisingOptions new_options(new_interval, false, kDefaultNoAdvFlags, false);
  advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, new_options, nullptr,
                                 GetSuccessCallback());
  RunLoopUntilIdle();
  EXPECT_TRUE(MoveLastStatus());

  EXPECT_EQ(new_interval.min(), fake_adv_state.interval_min);
  EXPECT_EQ(new_interval.max(), fake_adv_state.interval_max);
}

TEST_F(HCI_LegacyLowEnergyAdvertiserTest, StartWhileStarting) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data;
  DeviceAddress addr = kRandomAddress;

  const AdvertisingIntervalRange old_interval = kTestInterval;
  AdvertisingOptions old_options(old_interval, false, kDefaultNoAdvFlags, false);
  const AdvertisingIntervalRange new_interval(kTestInterval.min(), kTestInterval.min());
  AdvertisingOptions new_options(new_interval, false, kDefaultNoAdvFlags, false);

  advertiser()->StartAdvertising(addr, ad, scan_data, old_options, nullptr, [](auto) {});
  EXPECT_FALSE(test_device()->le_advertising_state().enabled);

  // This call should override the previous call and succeed with the new parameters.
  advertiser()->StartAdvertising(addr, ad, scan_data, new_options, nullptr, GetSuccessCallback());
  RunLoopUntilIdle();
  EXPECT_TRUE(MoveLastStatus());
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);
  EXPECT_EQ(new_interval.max(), test_device()->le_advertising_state().interval_max);
}

TEST_F(HCI_LegacyLowEnergyAdvertiserTest, StartWhileStopping) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data;
  DeviceAddress addr = kRandomAddress;
  AdvertisingOptions options(kTestInterval, false, kDefaultNoAdvFlags, false);

  // Get to a started state.
  advertiser()->StartAdvertising(addr, ad, scan_data, options, nullptr, GetSuccessCallback());
  RunLoopUntilIdle();
  EXPECT_TRUE(MoveLastStatus());
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);

  // Initiate a request to Stop and wait until it's partially in progress.
  bool enabled = true;
  bool was_disabled = false;
  auto adv_state_cb = [&] {
    enabled = test_device()->le_advertising_state().enabled;
    if (!was_disabled && !enabled) {
      was_disabled = true;

      // Starting now should cancel the stop sequence and succeed.
      advertiser()->StartAdvertising(addr, ad, scan_data, options, nullptr, GetSuccessCallback());
    }
  };
  test_device()->set_advertising_state_callback(adv_state_cb);

  EXPECT_TRUE(advertiser()->StopAdvertising(addr));

  // Advertising should have been momentarily disabled.
  RunLoopUntilIdle();
  EXPECT_TRUE(was_disabled);
  EXPECT_TRUE(enabled);
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);
}

// - StopAdvertisement noops when the advertisement address is wrong
// - Sets the advertisement data to null when stopped to prevent data leakage
//   (re-enable advertising without changing data, intercept)
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, StopAdvertisingConditions) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data;
  AdvertisingOptions options(kTestInterval, false, kDefaultNoAdvFlags, false);

  advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                 GetSuccessCallback());

  RunLoopUntilIdle();

  EXPECT_TRUE(MoveLastStatus());

  EXPECT_TRUE(test_device()->le_advertising_state().enabled);
  DynamicByteBuffer expected_ad(ad.CalculateBlockSize(/*include_flags=*/true));
  ad.WriteBlock(&expected_ad, kDefaultNoAdvFlags);
  EXPECT_TRUE(
      ContainersEqual(test_device()->le_advertising_state().advertised_view(), expected_ad));
  EXPECT_FALSE(advertiser()->StopAdvertising(kPublicAddress));

  EXPECT_TRUE(test_device()->le_advertising_state().enabled);
  EXPECT_TRUE(
      ContainersEqual(test_device()->le_advertising_state().advertised_view(), expected_ad));

  EXPECT_TRUE(advertiser()->StopAdvertising(kRandomAddress));

  RunLoopUntilIdle();

  EXPECT_FALSE(test_device()->le_advertising_state().enabled);
  EXPECT_EQ(0u, test_device()->le_advertising_state().advertised_view().size());
  EXPECT_EQ(0u, test_device()->le_advertising_state().scan_rsp_view().size());
}

// - Rejects StartAdvertising for a different address when Advertising already
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, NoAdvertiseTwice) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data;
  AdvertisingOptions options(kTestInterval, false, kDefaultNoAdvFlags, false);

  advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                 GetSuccessCallback());
  RunLoopUntilIdle();

  EXPECT_TRUE(MoveLastStatus());
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);

  DynamicByteBuffer expected_ad(ad.CalculateBlockSize(/*include_flags=*/true));
  ad.WriteBlock(&expected_ad, kDefaultNoAdvFlags);
  EXPECT_TRUE(
      ContainersEqual(test_device()->le_advertising_state().advertised_view(), expected_ad));
  EXPECT_EQ(hci::LEOwnAddressType::kRandom, test_device()->le_advertising_state().own_address_type);

  uint16_t new_appearance = 0x6789;
  ad.SetAppearance(new_appearance);
  advertiser()->StartAdvertising(kPublicAddress, ad, scan_data, options, nullptr,
                                 GetErrorCallback());
  RunLoopUntilIdle();

  // Should still be using the random address.
  EXPECT_EQ(hci::LEOwnAddressType::kRandom, test_device()->le_advertising_state().own_address_type);
  EXPECT_TRUE(MoveLastStatus());
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);
  EXPECT_TRUE(
      ContainersEqual(test_device()->le_advertising_state().advertised_view(), expected_ad));
}

// - Updates data and params for the same address when advertising already
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, AdvertiseUpdate) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data;
  AdvertisingOptions options(kTestInterval, false, kDefaultNoAdvFlags, false);

  advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                 GetSuccessCallback());
  RunLoopUntilIdle();

  EXPECT_TRUE(MoveLastStatus());
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);

  // The expected advertising data payload, with the flags.
  DynamicByteBuffer expected_ad(ad.CalculateBlockSize(/*include_flags=*/true));
  ad.WriteBlock(&expected_ad, kDefaultNoAdvFlags);
  EXPECT_TRUE(
      ContainersEqual(test_device()->le_advertising_state().advertised_view(), expected_ad));

  EXPECT_EQ(kTestInterval.min(), test_device()->le_advertising_state().interval_min);
  EXPECT_EQ(kTestInterval.max(), test_device()->le_advertising_state().interval_max);

  uint16_t new_appearance = 0x6789;
  ad.SetAppearance(new_appearance);

  const AdvertisingIntervalRange new_interval(kTestInterval.min() + 1, kTestInterval.max() - 1);
  AdvertisingOptions new_options(new_interval, false, kDefaultNoAdvFlags, false);
  advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, new_options, nullptr,
                                 GetSuccessCallback());
  RunLoopUntilIdle();

  EXPECT_TRUE(MoveLastStatus());
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);

  DynamicByteBuffer expected_new_ad(ad.CalculateBlockSize(/*include_flags=*/true));
  ad.WriteBlock(&expected_new_ad, kDefaultNoAdvFlags);
  EXPECT_TRUE(
      ContainersEqual(test_device()->le_advertising_state().advertised_view(), expected_new_ad));

  EXPECT_EQ(new_interval.min(), test_device()->le_advertising_state().interval_min);
  EXPECT_EQ(new_interval.max(), test_device()->le_advertising_state().interval_max);
}

// - Rejects anonymous advertisement (unsupported)
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, NoAnonymous) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data;
  AdvertisingOptions options(kTestInterval, true, kDefaultNoAdvFlags, false);

  advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                 GetErrorCallback());
  EXPECT_TRUE(MoveLastStatus());
  EXPECT_FALSE(test_device()->le_advertising_state().enabled);
}

TEST_F(HCI_LegacyLowEnergyAdvertiserTest, AllowsRandomAddressChange) {
  AdvertisingData scan_rsp;
  AdvertisingOptions options(kTestInterval, false, kDefaultNoAdvFlags, false);

  // The random address can be changed while not advertising.
  EXPECT_TRUE(advertiser()->AllowsRandomAddressChange());

  // The random address cannot be changed while starting to advertise.
  advertiser()->StartAdvertising(kRandomAddress, GetExampleData(), scan_rsp, options, nullptr,
                                 GetSuccessCallback());
  EXPECT_FALSE(test_device()->le_advertising_state().enabled);
  EXPECT_FALSE(advertiser()->AllowsRandomAddressChange());

  // The random address cannot be changed while advertising is enabled.
  RunLoopUntilIdle();
  EXPECT_TRUE(MoveLastStatus());
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);
  EXPECT_FALSE(advertiser()->AllowsRandomAddressChange());

  // The advertiser allows changing the address while advertising is getting
  // stopped.
  advertiser()->StopAdvertising(kRandomAddress);
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);
  EXPECT_TRUE(advertiser()->AllowsRandomAddressChange());

  RunLoopUntilIdle();
  EXPECT_FALSE(test_device()->le_advertising_state().enabled);
  EXPECT_TRUE(advertiser()->AllowsRandomAddressChange());
}

// Tests starting and stopping an advertisement when the TX power is requested.
// Validates the advertising and scan response data are correctly populated with the
// TX power.
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, StartAndStopWithTxPower) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data = GetExampleData();
  AdvertisingOptions options(kTestInterval, false, kDefaultNoAdvFlags, true);

  advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                 GetSuccessCallback());
  RunLoopUntilIdle();
  EXPECT_TRUE(MoveLastStatus());
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);

  // Verify the advertising and scan response data contains the newly populated TX Power Level.
  // See |../testing/fake_controller.cc:1585| for return value.
  ad.SetTxPower(0x9);
  DynamicByteBuffer expected_ad(ad.CalculateBlockSize(/*include_flags=*/true));
  ad.WriteBlock(&expected_ad, kDefaultNoAdvFlags);
  EXPECT_TRUE(
      ContainersEqual(test_device()->le_advertising_state().advertised_view(), expected_ad));

  scan_data.SetTxPower(0x9);
  DynamicByteBuffer expected_scan_rsp(ad.CalculateBlockSize(/*include_flags=*/false));
  scan_data.WriteBlock(&expected_scan_rsp, std::nullopt);
  EXPECT_TRUE(
      ContainersEqual(test_device()->le_advertising_state().scan_rsp_view(), expected_scan_rsp));

  EXPECT_TRUE(advertiser()->StopAdvertising(kRandomAddress));
  RunLoopUntilIdle();
  EXPECT_FALSE(test_device()->le_advertising_state().enabled);
}

// Tests sending a second StartAdvertising command while the first one is outstanding,
// with TX power enabled.
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, StartWhileStartingWithTxPower) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data;
  DeviceAddress addr = kRandomAddress;

  const AdvertisingIntervalRange old_interval = kTestInterval;
  AdvertisingOptions options(old_interval, false, kDefaultNoAdvFlags, true);
  const AdvertisingIntervalRange new_interval(kTestInterval.min(), kTestInterval.min());
  AdvertisingOptions new_options(new_interval, false, kDefaultNoAdvFlags, true);

  advertiser()->StartAdvertising(addr, ad, scan_data, options, nullptr, [](auto) {});
  EXPECT_FALSE(test_device()->le_advertising_state().enabled);

  // This call should override the previous call and succeed with the new parameters.
  advertiser()->StartAdvertising(addr, ad, scan_data, new_options, nullptr, GetSuccessCallback());
  RunLoopUntilIdle();
  EXPECT_TRUE(MoveLastStatus());
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);
  EXPECT_EQ(new_interval.max(), test_device()->le_advertising_state().interval_max);

  // Verify the advertising data contains the newly populated TX Power Level.
  // Since the scan response data is empty, it's power level should not be populated.
  // See |../testing/fake_controller.cc:1585| for return value.
  ad.SetTxPower(0x9);
  DynamicByteBuffer expected_ad(ad.CalculateBlockSize(/*include_flags=*/true));
  ad.WriteBlock(&expected_ad, kDefaultNoAdvFlags);
  EXPECT_TRUE(
      ContainersEqual(test_device()->le_advertising_state().advertised_view(), expected_ad));
  EXPECT_TRUE(
      ContainersEqual(test_device()->le_advertising_state().scan_rsp_view(), DynamicByteBuffer()));
}

// Test that the second StartAdvertising call (with no TX Power requested) successfully supercedes
// the first ongoing StartAdvertising call (with TX Power requested).
// Validates the advertised data does not include the TX power.
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, StartWhileStartingTxPowerRequestedThenNotRequested) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data;
  DeviceAddress addr = kRandomAddress;

  const AdvertisingIntervalRange old_interval = kTestInterval;
  AdvertisingOptions options(old_interval, false, kDefaultNoAdvFlags, true);
  const AdvertisingIntervalRange new_interval(kTestInterval.min(), kTestInterval.min());
  AdvertisingOptions new_options(new_interval, false, kDefaultNoAdvFlags, false);

  advertiser()->StartAdvertising(addr, ad, scan_data, options, nullptr, [](auto) {});
  EXPECT_FALSE(test_device()->le_advertising_state().enabled);

  // This call should override the previous call and succeed with the new parameters.
  advertiser()->StartAdvertising(addr, ad, scan_data, new_options, nullptr, GetSuccessCallback());
  RunLoopUntilIdle();
  EXPECT_TRUE(MoveLastStatus());
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);
  EXPECT_EQ(new_interval.max(), test_device()->le_advertising_state().interval_max);

  // Verify the advertising data doesn't contain a new TX Power Level.
  DynamicByteBuffer expected_ad(ad.CalculateBlockSize(/*include_flags=*/true));
  ad.WriteBlock(&expected_ad, kDefaultNoAdvFlags);
  EXPECT_TRUE(
      ContainersEqual(test_device()->le_advertising_state().advertised_view(), expected_ad));
}

// Test that the second StartAdvertising call (with TX Power requested) successfully supercedes
// the first ongoing StartAdvertising call (no TX Power requested).
// Validates the advertised data includes the TX power.
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, StartingWhileStartingTxPowerNotRequestedThenRequested) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data;
  DeviceAddress addr = kRandomAddress;

  const AdvertisingIntervalRange old_interval = kTestInterval;
  AdvertisingOptions options(old_interval, false, kDefaultNoAdvFlags, false);
  const AdvertisingIntervalRange new_interval(kTestInterval.min(), kTestInterval.min());
  AdvertisingOptions new_options(new_interval, false, kDefaultNoAdvFlags, true);

  advertiser()->StartAdvertising(addr, ad, scan_data, options, nullptr, [](auto) {});
  EXPECT_FALSE(test_device()->le_advertising_state().enabled);

  // This call should override the previous call and succeed with the new parameters.
  advertiser()->StartAdvertising(addr, ad, scan_data, new_options, nullptr, GetSuccessCallback());
  RunLoopUntilIdle();
  EXPECT_TRUE(MoveLastStatus());
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);
  EXPECT_EQ(new_interval.max(), test_device()->le_advertising_state().interval_max);

  // Verify the advertising data doesn't contain a new TX Power Level.
  ad.SetTxPower(0x9);
  DynamicByteBuffer expected_ad(ad.CalculateBlockSize(/*include_flags=*/true));
  ad.WriteBlock(&expected_ad, kDefaultNoAdvFlags);
  EXPECT_TRUE(
      ContainersEqual(test_device()->le_advertising_state().advertised_view(), expected_ad));
  EXPECT_TRUE(
      ContainersEqual(test_device()->le_advertising_state().scan_rsp_view(), DynamicByteBuffer()));
}

// Tests that advertising gets enabled successfully with the updated parameters if
// StartAdvertising is called during a TX Power Level read.
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, StartWhileTxPowerReadSuccess) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data;
  DeviceAddress addr = kRandomAddress;

  const AdvertisingIntervalRange old_interval = kTestInterval;
  AdvertisingOptions options(old_interval, false, kDefaultNoAdvFlags, true);
  const AdvertisingIntervalRange new_interval(kTestInterval.min(), kTestInterval.min());
  AdvertisingOptions new_options(new_interval, false, kDefaultNoAdvFlags, true);

  // Hold off on responding to the first TX Power Level Read command.
  test_device()->set_tx_power_level_read_response_flag(/*respond=*/false);

  advertiser()->StartAdvertising(addr, ad, scan_data, options, nullptr, GetErrorCallback());
  EXPECT_FALSE(test_device()->le_advertising_state().enabled);

  RunLoopUntilIdle();
  // At this point in time, the first StartAdvertising call is still waiting on the TX Power Level
  // Read response.

  // Queue up the next StartAdvertising call.
  // This call should override the previous call's advertising parameters.
  test_device()->set_tx_power_level_read_response_flag(/*respond=*/true);
  advertiser()->StartAdvertising(addr, ad, scan_data, new_options, nullptr, GetSuccessCallback());

  // Explicitly respond to the first TX Power Level read command.
  test_device()->SendTxPowerLevelReadResponse();

  RunLoopUntilIdle();
  EXPECT_TRUE(test_device()->le_advertising_state().enabled);
  EXPECT_EQ(new_interval.max(), test_device()->le_advertising_state().interval_max);
}

// Tests that advertising does not get enabled if the TX Power read fails.
TEST_F(HCI_LegacyLowEnergyAdvertiserTest, StartAdvertisingReadTxPowerFails) {
  AdvertisingData ad = GetExampleData();
  AdvertisingData scan_data;
  AdvertisingOptions options(kTestInterval, false, kDefaultNoAdvFlags, true);

  // Simulate failure for Read TX Power operation.
  test_device()->SetDefaultResponseStatus(kLEReadAdvertisingChannelTxPower,
                                          hci::StatusCode::kHardwareFailure);

  advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                 GetErrorCallback());
  RunLoopUntilIdle();
  auto status = MoveLastStatus();
  ASSERT_TRUE(status);
  EXPECT_EQ(HostError::kProtocolError, status->error());
}

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