// 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/public/pw_bluetooth_sapphire/internal/host/gap/low_energy_advertising_manager.h"

#include <map>

#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/advertising_data.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/assert.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/macros.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/hci/connection.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/hci/fake_local_address_delegate.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/hci/fake_low_energy_connection.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/controller_test.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/fake_controller.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/transport/emboss_control_packets.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/transport/error.h"

namespace bt {
using testing::FakeController;

namespace gap {
namespace {
namespace pwemb = pw::bluetooth::emboss;
using TestingBase = bt::testing::FakeDispatcherControllerTest<FakeController>;

constexpr size_t kDefaultMaxAdSize = 23;
constexpr size_t kDefaultFakeAdSize = 20;
constexpr AdvertisingInterval kTestInterval = AdvertisingInterval::FAST1;

const DeviceAddress kRandomAddress(DeviceAddress::Type::kLERandom,
                                   {0x55, 0x44, 0x33, 0x22, 0x11, 0x00});

void NopConnectCallback(AdvertisementId, std::unique_ptr<hci::Connection>) {}

struct AdvertisementStatus {
  AdvertisingData data;
  AdvertisingData scan_rsp;
  bool anonymous;
  uint16_t interval_min;
  uint16_t interval_max;
  bool extended_pdu;
  hci::LowEnergyAdvertiser::ConnectionCallback connect_cb;
};

// LowEnergyAdvertiser for testing purposes:
//  - Reports mas_ad_size supported
//  - Actually just accepts all ads and stores them in ad_store
class FakeLowEnergyAdvertiser final : public hci::LowEnergyAdvertiser {
 public:
  FakeLowEnergyAdvertiser(
      const hci::Transport::WeakPtr& hci,
      std::unordered_map<DeviceAddress, AdvertisementStatus>* ad_store)
      : hci::LowEnergyAdvertiser(hci, kDefaultMaxAdSize),
        ads_(ad_store),
        hci_(hci) {
    BT_ASSERT(ads_);
  }

  ~FakeLowEnergyAdvertiser() override = default;

  size_t MaxAdvertisements() const override { return 1; }

  bool AllowsRandomAddressChange() const override { return true; }

  void StartAdvertising(const DeviceAddress& address,
                        const AdvertisingData& data,
                        const AdvertisingData& scan_rsp,
                        const AdvertisingOptions& options,
                        ConnectionCallback connect_callback,
                        hci::ResultFunction<> result_callback) override {
    if (pending_error_.is_error()) {
      result_callback(pending_error_);
      pending_error_ = fit::ok();
      return;
    }

    fit::result<HostError> result =
        CanStartAdvertising(address, data, scan_rsp, options, connect_callback);
    if (result.is_error()) {
      result_callback(ToResult(result.error_value()));
      return;
    }

    AdvertisementStatus new_status;
    data.Copy(&new_status.data);
    scan_rsp.Copy(&new_status.scan_rsp);
    new_status.connect_cb = std::move(connect_callback);
    new_status.interval_min = options.interval.min();
    new_status.interval_max = options.interval.max();
    new_status.anonymous = options.anonymous;
    new_status.extended_pdu = options.extended_pdu;
    ads_->emplace(address, std::move(new_status));
    result_callback(fit::ok());
  }

  void StopAdvertising(const DeviceAddress& address,
                       bool extended_pdu) override {
    ads_->erase(address);
  }

  void OnIncomingConnection(
      hci_spec::ConnectionHandle handle,
      pwemb::ConnectionRole role,
      const DeviceAddress& peer_address,
      const hci_spec::LEConnectionParameters& conn_params) override {
    // Right now, we call the first callback, because we can't call any other
    // ones.
    // TODO(jamuraa): make this send it to the correct callback once we can
    // determine which one that is.
    const auto& cb = ads_->begin()->second.connect_cb;
    if (cb) {
      cb(std::make_unique<hci::testing::FakeLowEnergyConnection>(
          handle, ads_->begin()->first, peer_address, role, hci_));
    }
  }

  // Sets this faker up to send an error back from the next StartAdvertising
  // call. Set to success to disable a previously called error.
  void ErrorOnNext(hci::Result<> error_status) {
    pending_error_ = error_status;
  }

 private:
  hci::EmbossCommandPacket BuildEnablePacket(
      const DeviceAddress& address,
      pw::bluetooth::emboss::GenericEnableParam enable,
      bool extended_pdu) override {
    return hci::EmbossCommandPacket::New<
        pwemb::LESetExtendedAdvertisingEnableDataWriter>(
        hci_spec::kLESetExtendedAdvertisingEnable);
  }

  std::optional<hci::EmbossCommandPacket> BuildSetAdvertisingParams(
      const DeviceAddress& address,
      const AdvertisingEventProperties& properties,
      pwemb::LEOwnAddressType own_address_type,
      const hci::AdvertisingIntervalRange& interval,
      bool extended_pdu) override {
    return std::nullopt;
  }

  std::vector<hci::EmbossCommandPacket> BuildSetAdvertisingData(
      const DeviceAddress& address,
      const AdvertisingData& data,
      AdvFlags flags,
      bool extended_pdu) override {
    hci::EmbossCommandPacket packet =
        hci::EmbossCommandPacket::New<pwemb::LESetAdvertisingDataCommandWriter>(
            hci_spec::kLESetAdvertisingData);

    std::vector<hci::EmbossCommandPacket> packets;
    packets.push_back(std::move(packet));
    return packets;
  }

  hci::EmbossCommandPacket BuildUnsetAdvertisingData(
      const DeviceAddress& address, bool extended_pdu) override {
    return hci::EmbossCommandPacket::New<
        pwemb::LESetAdvertisingDataCommandWriter>(
        hci_spec::kLESetAdvertisingData);
  }

  std::vector<hci::EmbossCommandPacket> BuildSetScanResponse(
      const DeviceAddress& address,
      const AdvertisingData& scan_rsp,
      bool extended_pdu) override {
    hci::EmbossCommandPacket packet = hci::EmbossCommandPacket::New<
        pwemb::LESetScanResponseDataCommandWriter>(
        hci_spec::kLESetScanResponseData);

    std::vector<hci::EmbossCommandPacket> packets;
    packets.push_back(std::move(packet));
    return packets;
  }

  hci::EmbossCommandPacket BuildUnsetScanResponse(const DeviceAddress& address,
                                                  bool extended_pdu) override {
    return hci::EmbossCommandPacket::New<
        pwemb::LESetScanResponseDataCommandWriter>(
        hci_spec::kLESetScanResponseData);
  }

  hci::EmbossCommandPacket BuildRemoveAdvertisingSet(
      const DeviceAddress& address, bool extended_pdu) override {
    return hci::EmbossCommandPacket::New<
        pwemb::LERemoveAdvertisingSetCommandWriter>(
        hci_spec::kLERemoveAdvertisingSet);
  }

  std::unordered_map<DeviceAddress, AdvertisementStatus>* ads_;
  hci::Result<> pending_error_ = fit::ok();
  hci::Transport::WeakPtr hci_;

  BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(FakeLowEnergyAdvertiser);
};

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

 protected:
  void SetUp() override {
    TestingBase::SetUp();
    InitializeACLDataChannel();

    fake_address_delegate_.set_local_address(kRandomAddress);
    MakeFakeAdvertiser();
    MakeAdvertisingManager();
  }

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

  // Makes some fake advertising data of a specific |packed_size|
  AdvertisingData CreateFakeAdvertisingData(
      size_t packed_size = kDefaultFakeAdSize) {
    AdvertisingData result;
    StaticByteBuffer buffer(
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08);
    size_t bytes_left = packed_size;
    while (bytes_left > 0) {
      // Each field to take 10 bytes total, unless the next header (4 bytes)
      // won't fit. In which case we add enough bytes to finish up.
      size_t data_bytes = bytes_left < 14 ? (bytes_left - 4) : 6;
      EXPECT_TRUE(result.SetManufacturerData(0xb000 + bytes_left,
                                             buffer.view(0, data_bytes)));
      bytes_left = packed_size - result.CalculateBlockSize();
    }
    return result;
  }

  LowEnergyAdvertisingManager::AdvertisingStatusCallback GetErrorCallback() {
    return [this](AdvertisementInstance instance, hci::Result<> status) {
      EXPECT_EQ(kInvalidAdvertisementId, instance.id());
      EXPECT_TRUE(status.is_error());
      last_status_ = status;
    };
  }

  LowEnergyAdvertisingManager::AdvertisingStatusCallback GetSuccessCallback() {
    return [this](AdvertisementInstance instance, hci::Result<> status) {
      EXPECT_NE(kInvalidAdvertisementId, instance.id());
      EXPECT_EQ(fit::ok(), status);
      last_instance_ = std::move(instance);
      last_status_ = status;
    };
  }

  void MakeFakeAdvertiser() {
    advertiser_ = std::make_unique<FakeLowEnergyAdvertiser>(
        transport()->GetWeakPtr(), &ad_store_);
  }

  void MakeAdvertisingManager() {
    adv_mgr_ = std::make_unique<LowEnergyAdvertisingManager>(
        advertiser(), &fake_address_delegate_);
  }

  LowEnergyAdvertisingManager* adv_mgr() const { return adv_mgr_.get(); }
  const std::unordered_map<DeviceAddress, AdvertisementStatus>& ad_store() {
    return ad_store_;
  }
  AdvertisementId last_ad_id() const { return last_instance_.id(); }

  // Returns the currently active advertising state. This is useful for tests
  // that want to verify advertising parameters when there is a single known
  // advertisement. Returns nullptr if the number of advertisements are not
  // equal to one.
  const AdvertisementStatus* current_adv() const {
    if (ad_store_.size() != 1u) {
      return nullptr;
    }
    return &ad_store_.begin()->second;
  }

  // Returns and clears the last callback status. This resets the state to
  // detect another callback.
  std::optional<hci::Result<>> last_status() { return last_status_; }

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

 private:
  hci::FakeLocalAddressDelegate fake_address_delegate_{dispatcher()};

  // TODO(armansito): The address mapping is currently broken since the
  // gap::LEAM always assigns the controller random address. Make this track
  // each instance by instance ID instead once the layering issues have been
  // fixed.
  std::unordered_map<DeviceAddress, AdvertisementStatus> ad_store_;
  AdvertisementInstance last_instance_;
  std::optional<hci::Result<>> last_status_;
  std::unique_ptr<FakeLowEnergyAdvertiser> advertiser_;
  std::unique_ptr<LowEnergyAdvertisingManager> adv_mgr_;

  BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(LowEnergyAdvertisingManagerTest);
};

// Tests:
//  - When the advertiser succeeds, the callback is called with the success
TEST_F(LowEnergyAdvertisingManagerTest, Success) {
  EXPECT_FALSE(adv_mgr()->advertising());
  adv_mgr()->StartAdvertising(CreateFakeAdvertisingData(),
                              AdvertisingData(),
                              /*connect_callback=*/nullptr,
                              kTestInterval,
                              /*extended_pdu=*/false,
                              /*anonymous=*/false,
                              /*include_tx_power_level=*/false,
                              GetSuccessCallback());

  RunUntilIdle();

  EXPECT_TRUE(last_status());
  ASSERT_EQ(1u, ad_store().size());
  EXPECT_TRUE(adv_mgr()->advertising());

  // Verify that the advertiser uses the requested local address.
  EXPECT_EQ(kRandomAddress, ad_store().begin()->first);
}

TEST_F(LowEnergyAdvertisingManagerTest, DataSize) {
  adv_mgr()->StartAdvertising(CreateFakeAdvertisingData(),
                              AdvertisingData(),
                              /*connect_callback=*/nullptr,
                              kTestInterval,
                              /*extended_pdu=*/true,
                              /*anonymous=*/false,
                              /*include_tx_power_level=*/false,
                              GetSuccessCallback());

  RunUntilIdle();

  EXPECT_TRUE(last_status());
  EXPECT_EQ(1u, ad_store().size());

  adv_mgr()->StartAdvertising(CreateFakeAdvertisingData(kDefaultMaxAdSize + 1),
                              AdvertisingData(),
                              /*connect_callback=*/nullptr,
                              kTestInterval,
                              /*extended_pdu=*/true,
                              /*anonymous=*/false,
                              /*include_tx_power_level=*/false,
                              GetErrorCallback());

  RunUntilIdle();

  EXPECT_TRUE(last_status());
  EXPECT_EQ(1u, ad_store().size());
}

// TODO(https://fxbug.dev/42083437): Revise this test to use multiple
// advertising instances when multi-advertising is supported.
//  - Stopping one that is registered stops it in the advertiser
//    (and stops the right address)
//  - Stopping an advertisement that isn't registered returns false
TEST_F(LowEnergyAdvertisingManagerTest, RegisterUnregister) {
  EXPECT_FALSE(adv_mgr()->StopAdvertising(kInvalidAdvertisementId));

  adv_mgr()->StartAdvertising(CreateFakeAdvertisingData(),
                              AdvertisingData(),
                              /*connect_callback=*/nullptr,
                              kTestInterval,
                              /*extended_pdu=*/false,
                              /*anonymous=*/false,
                              /*include_tx_power_level=*/false,
                              GetSuccessCallback());

  RunUntilIdle();

  EXPECT_TRUE(last_status());
  EXPECT_EQ(1u, ad_store().size());
  EXPECT_TRUE(adv_mgr()->advertising());

  EXPECT_TRUE(adv_mgr()->StopAdvertising(last_ad_id()));
  EXPECT_TRUE(ad_store().empty());
  EXPECT_FALSE(adv_mgr()->advertising());

  EXPECT_FALSE(adv_mgr()->StopAdvertising(last_ad_id()));
  EXPECT_TRUE(ad_store().empty());
}

//  - When the advertiser returns an error, we return an error
TEST_F(LowEnergyAdvertisingManagerTest, AdvertiserError) {
  advertiser()->ErrorOnNext(
      ToResult(pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS));

  EXPECT_FALSE(adv_mgr()->advertising());
  adv_mgr()->StartAdvertising(CreateFakeAdvertisingData(),
                              AdvertisingData(),
                              /*connect_callback=*/nullptr,
                              kTestInterval,
                              /*extended_pdu=*/false,
                              /*anonymous=*/false,
                              /*include_tx_power_level=*/false,
                              GetErrorCallback());
  RunUntilIdle();

  EXPECT_TRUE(last_status());
  EXPECT_FALSE(adv_mgr()->advertising());
}

//  - It calls the connectable callback correctly when connected to
TEST_F(LowEnergyAdvertisingManagerTest, ConnectCallback) {
  std::unique_ptr<hci::LowEnergyConnection> link;
  AdvertisementId advertised_id = kInvalidAdvertisementId;

  auto connect_cb = [&](AdvertisementId connected_id,
                        std::unique_ptr<hci::LowEnergyConnection> cb_link) {
    link = std::move(cb_link);
    EXPECT_EQ(advertised_id, connected_id);
  };
  adv_mgr()->StartAdvertising(CreateFakeAdvertisingData(),
                              AdvertisingData(),
                              connect_cb,
                              kTestInterval,
                              /*extended_pdu=*/false,
                              /*anonymous=*/false,
                              /*include_tx_power_level=*/false,
                              GetSuccessCallback());

  RunUntilIdle();

  EXPECT_TRUE(last_status());
  advertised_id = last_ad_id();

  DeviceAddress peer_address(DeviceAddress::Type::kLEPublic,
                             {3, 2, 1, 1, 2, 3});
  advertiser()->OnIncomingConnection(1,
                                     pwemb::ConnectionRole::PERIPHERAL,
                                     peer_address,
                                     hci_spec::LEConnectionParameters());
  RunUntilIdle();
  ASSERT_TRUE(link);

  // Make sure that the link has the correct local and peer addresses
  // assigned.
  EXPECT_EQ(kRandomAddress, link->local_address());
  EXPECT_EQ(peer_address, link->peer_address());
}

//  - Error: Connectable and Anonymous at the same time
TEST_F(LowEnergyAdvertisingManagerTest, ConnectAdvertiseError) {
  auto connect_cb = [](AdvertisementId connected_id,
                       std::unique_ptr<hci::LowEnergyConnection> conn) {};

  adv_mgr()->StartAdvertising(CreateFakeAdvertisingData(),
                              AdvertisingData(),
                              connect_cb,
                              kTestInterval,
                              /*extended_pdu=*/false,
                              /*anonymous=*/true,
                              /*include_tx_power_level=*/false,
                              GetErrorCallback());

  EXPECT_TRUE(last_status());
}

// Passes the values for the data on. (anonymous, data, scan_rsp)
TEST_F(LowEnergyAdvertisingManagerTest, SendsCorrectData) {
  adv_mgr()->StartAdvertising(CreateFakeAdvertisingData(),
                              CreateFakeAdvertisingData(/*packed_size=*/21),
                              /*connect_callback=*/nullptr,
                              kTestInterval,
                              /*extended_pdu=*/false,
                              /*anonymous=*/false,
                              /*include_tx_power_level=*/false,
                              GetSuccessCallback());

  RunUntilIdle();

  EXPECT_TRUE(last_status());
  EXPECT_EQ(1u, ad_store().size());

  auto ad_status = &ad_store().begin()->second;

  AdvertisingData expected_ad = CreateFakeAdvertisingData();
  AdvertisingData expected_scan_rsp =
      CreateFakeAdvertisingData(/*packed_size=*/21);
  EXPECT_EQ(expected_ad, ad_status->data);
  EXPECT_EQ(expected_scan_rsp, ad_status->scan_rsp);
  EXPECT_EQ(false, ad_status->anonymous);
  EXPECT_EQ(nullptr, ad_status->connect_cb);
}

// Test that the AdvertisingInterval values map to the spec defined constants
// (NOTE: this might change in the future in favor of a more advanced policy
// for managing the intervals; for now they get mapped to recommended values
// from Vol 3, Part C, Appendix A).
TEST_F(LowEnergyAdvertisingManagerTest, ConnectableAdvertisingIntervals) {
  adv_mgr()->StartAdvertising(CreateFakeAdvertisingData(),
                              CreateFakeAdvertisingData(/*packed_size=*/21),
                              NopConnectCallback,
                              AdvertisingInterval::FAST1,
                              /*extended_pdu=*/false,
                              /*anonymous=*/false,
                              /*include_tx_power_level=*/false,
                              GetSuccessCallback());
  RunUntilIdle();
  ASSERT_TRUE(last_status());
  ASSERT_TRUE(current_adv());
  EXPECT_EQ(kLEAdvertisingFastIntervalMin1, current_adv()->interval_min);
  EXPECT_EQ(kLEAdvertisingFastIntervalMax1, current_adv()->interval_max);
  ASSERT_TRUE(adv_mgr()->StopAdvertising(last_ad_id()));

  adv_mgr()->StartAdvertising(CreateFakeAdvertisingData(),
                              CreateFakeAdvertisingData(/*packed_size=*/21),
                              NopConnectCallback,
                              AdvertisingInterval::FAST2,
                              /*extended_pdu=*/false,
                              /*anonymous=*/false,
                              /*include_tx_power_level=*/false,
                              GetSuccessCallback());
  RunUntilIdle();
  ASSERT_TRUE(last_status());
  ASSERT_TRUE(current_adv());
  EXPECT_EQ(kLEAdvertisingFastIntervalMin2, current_adv()->interval_min);
  EXPECT_EQ(kLEAdvertisingFastIntervalMax2, current_adv()->interval_max);
  ASSERT_TRUE(adv_mgr()->StopAdvertising(last_ad_id()));

  adv_mgr()->StartAdvertising(CreateFakeAdvertisingData(),
                              CreateFakeAdvertisingData(/*packed_size=*/21),
                              NopConnectCallback,
                              AdvertisingInterval::SLOW,
                              /*extended_pdu=*/false,
                              /*anonymous=*/false,
                              /*include_tx_power_level=*/false,
                              GetSuccessCallback());
  RunUntilIdle();
  ASSERT_TRUE(last_status());
  ASSERT_TRUE(current_adv());
  EXPECT_EQ(kLEAdvertisingSlowIntervalMin, current_adv()->interval_min);
  EXPECT_EQ(kLEAdvertisingSlowIntervalMax, current_adv()->interval_max);
  ASSERT_TRUE(adv_mgr()->StopAdvertising(last_ad_id()));
}

TEST_F(LowEnergyAdvertisingManagerTest, NonConnectableAdvertisingIntervals) {
  AdvertisingData fake_ad = CreateFakeAdvertisingData();
  AdvertisingData scan_rsp = CreateFakeAdvertisingData(21 /* size of ad */);

  // We expect FAST1 to fall back to FAST2 due to specification recommendation
  // (Vol 3, Part C, Appendix A) and lack of support for non-connectable
  // advertising with FAST1 parameters on certain controllers.
  adv_mgr()->StartAdvertising(CreateFakeAdvertisingData(),
                              CreateFakeAdvertisingData(/*packed_size=*/21),
                              /*connect_callback=*/nullptr,
                              AdvertisingInterval::FAST1,
                              /*extended_pdu=*/false,
                              /*anonymous=*/false,
                              /*include_tx_power_level=*/false,
                              GetSuccessCallback());
  RunUntilIdle();
  ASSERT_TRUE(last_status());
  ASSERT_TRUE(current_adv());
  EXPECT_EQ(kLEAdvertisingFastIntervalMin2, current_adv()->interval_min);
  EXPECT_EQ(kLEAdvertisingFastIntervalMax2, current_adv()->interval_max);
  ASSERT_TRUE(adv_mgr()->StopAdvertising(last_ad_id()));

  adv_mgr()->StartAdvertising(CreateFakeAdvertisingData(),
                              CreateFakeAdvertisingData(/*packed_size=*/21),
                              /*connect_callback=*/nullptr,
                              AdvertisingInterval::FAST2,
                              /*extended_pdu=*/false,
                              /*anonymous=*/false,
                              /*include_tx_power_level=*/false,
                              GetSuccessCallback());
  RunUntilIdle();
  ASSERT_TRUE(last_status());
  ASSERT_TRUE(current_adv());
  EXPECT_EQ(kLEAdvertisingFastIntervalMin2, current_adv()->interval_min);
  EXPECT_EQ(kLEAdvertisingFastIntervalMax2, current_adv()->interval_max);
  ASSERT_TRUE(adv_mgr()->StopAdvertising(last_ad_id()));

  adv_mgr()->StartAdvertising(CreateFakeAdvertisingData(),
                              CreateFakeAdvertisingData(/*packed_size=*/21),
                              /*connect_callback=*/nullptr,
                              AdvertisingInterval::SLOW,
                              /*extended_pdu=*/false,
                              /*anonymous=*/false,
                              /*include_tx_power_level=*/false,
                              GetSuccessCallback());
  RunUntilIdle();
  ASSERT_TRUE(last_status());
  ASSERT_TRUE(current_adv());
  EXPECT_EQ(kLEAdvertisingSlowIntervalMin, current_adv()->interval_min);
  EXPECT_EQ(kLEAdvertisingSlowIntervalMax, current_adv()->interval_max);
  ASSERT_TRUE(adv_mgr()->StopAdvertising(last_ad_id()));
}

TEST_F(LowEnergyAdvertisingManagerTest, DestroyingInstanceStopsAdvertisement) {
  {
    AdvertisementInstance instance;
    adv_mgr()->StartAdvertising(AdvertisingData(),
                                AdvertisingData(),
                                /*connect_callback=*/nullptr,
                                AdvertisingInterval::FAST1,
                                /*extended_pdu=*/false,
                                /*anonymous=*/false,
                                /*include_tx_power_level=*/false,
                                [&](AdvertisementInstance i, auto status) {
                                  ASSERT_EQ(fit::ok(), status);
                                  instance = std::move(i);
                                });
    RunUntilIdle();
    EXPECT_TRUE(adv_mgr()->advertising());

    // Destroying |instance| should stop the advertisement.
  }

  RunUntilIdle();
  EXPECT_FALSE(adv_mgr()->advertising());
}

TEST_F(LowEnergyAdvertisingManagerTest, MovingIntoInstanceStopsAdvertisement) {
  AdvertisementInstance instance;
  adv_mgr()->StartAdvertising(AdvertisingData(),
                              AdvertisingData(),
                              /*connect_callback=*/nullptr,
                              AdvertisingInterval::FAST1,
                              /*extended_pdu=*/false,
                              /*anonymous=*/false,
                              /*include_tx_power_level=*/false,
                              [&](AdvertisementInstance i, auto status) {
                                ASSERT_EQ(fit::ok(), status);
                                instance = std::move(i);
                              });
  RunUntilIdle();
  EXPECT_TRUE(adv_mgr()->advertising());

  // Destroying |instance| by invoking the move assignment operator should
  // stop the advertisement.
  instance = {};
  RunUntilIdle();
  EXPECT_FALSE(adv_mgr()->advertising());
}

TEST_F(LowEnergyAdvertisingManagerTest,
       MovingInstanceTransfersOwnershipOfAdvertisement) {
  auto instance = std::make_unique<AdvertisementInstance>();
  adv_mgr()->StartAdvertising(AdvertisingData(),
                              AdvertisingData(),
                              /*connect_callback=*/nullptr,
                              AdvertisingInterval::FAST1,
                              /*extended_pdu=*/false,
                              /*anonymous=*/false,
                              /*include_tx_power_level=*/false,
                              [&](AdvertisementInstance i, auto status) {
                                ASSERT_EQ(fit::ok(), status);
                                *instance = std::move(i);
                              });
  RunUntilIdle();
  EXPECT_TRUE(adv_mgr()->advertising());

  // Moving |instance| should transfer the ownership of the advertisement
  // (assignment).
  {
    AdvertisementInstance move_assigned_instance = std::move(*instance);

    // Explicitly clearing the old instance should have no effect.
    *instance = {};
    RunUntilIdle();
    EXPECT_TRUE(adv_mgr()->advertising());

    *instance = std::move(move_assigned_instance);
  }

  // Advertisement should not stop when |move_assigned_instance| goes out of
  // scope as it no longer owns the advertisement.
  RunUntilIdle();
  EXPECT_TRUE(adv_mgr()->advertising());

  // Moving |instance| should transfer the ownership of the advertisement
  // (move-constructor).
  {
    AdvertisementInstance move_constructed_instance(std::move(*instance));

    // Explicitly destroying the old instance should have no effect.
    instance.reset();
    RunUntilIdle();
    EXPECT_TRUE(adv_mgr()->advertising());
  }

  // Advertisement should stop when |move_constructed_instance| goes out of
  // scope.
  RunUntilIdle();
  EXPECT_FALSE(adv_mgr()->advertising());
}

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